文章目录
- 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
@RestControllerpublic class OrderController{@AutowiredSynchronizedByKey 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();}}
}
学习视频链接