文章目录
- synchronized
- synchronized 作用当前对象
- synchronized 作用订单号条件
- synchronized 作用订单号字符串条件
- ReentrantLock 加 ConcurrentHashMap
需求: 同一个订单才加同步锁,不同订单可并行
synchronized
synchronized是Java中的关键字,是一种同步锁,是原生语法层面的互斥,需要jvm实现。它修饰的对象有以下几种:
1. 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象;
2. 修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象;
3. 修改一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象;
4. 修改一个类,其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象。
synchronized 作用当前对象
测试效果:
一)线程1 与 线程2 ,结果 线程1结束了线程2才开始。
synchronized 作用订单号条件
测试效果:
一)线程1 与 线程2 ,结果 线程1线程2可以同时开始。
二)线程1 与 线程1 ,结果 线程1与另一个线程1同时开始
。
synchronized 的锁不是比较字符串,而是对象,所以每次请求进来的orderId不是同一个对象。
synchronized 作用订单号字符串条件
把 synchronized 锁的 orderId 放在常量池中,那每次请求进来的就是同一个对象。
测试效果:
一)线程1 与 线程1 ,结果 线程1线程1锁住了。
二)线程1 与 线程2,结果 线程1与线程2同时开始。
ReentrantLock 加 ConcurrentHashMap
ReentrantLock它是JDK 1.5之后提供的API层面的互斥锁,需要lock()和unlock()方法配合try/finally语句块来完成
------------------------------------------------controller
@RestController
public class OrderController{
@Autowired
SynchronizedByKey synchronizedByKey;
@ResponseBody
@RequestMapping("")
pubilc Map<String,Object> process(@PathVariable("orderId")String orderId){
SynchronizedByKey.exec(orderId,() ->{
logger.debug("[{}] 开始",orderId);
logger.debug("[{}] 结束",orderId);
});
}
}
------------------------------------------------SynchronizedByKey
public class SynchronizedByKey {
Map<String,ReentrantLock> mutexCache = new ConcurrentHashMap<>;
public void exec(String key,Runnable statement){
ReentrantLock mutex4Key = null;
ReentrantLock mutexInCache;
do{
if(mutex4Key != null){
mutex4Key.unlock();
}
mutex4Key = mutexCache.computeIfAbsent(key, k -> new ReentrantLock());
mutex4Key.lock();
/* lock()后再根据key去mutexCache取一把锁(mutexInCache),
极端情况:
1.我刚刚拿到了这把锁(mutexInCache),又从map里取的时候它为空了,说明我刚刚拿到的那么锁被remove掉了;
2.我刚刚拿到了这把锁(mutexInCache),被新进来的线程(都是001)又创建了一把新锁覆盖了,
所以mutex4Key 和 mutexInCache 不等; */
mutexInCache = mutexCache.get(key);
} while(mutexInCache == null || mutex4Key != mutexInCache);
try{
statement.run();
} finally{
if(mutex4Key.getQueueLength() == 0){
mutexCache.remove(key);
}
mutex4Key.unlock();
}
}
}
学习视频链接