解决问题
1、批量订单,同一个订单只能一个一个执行.
private static Map<Long, ReentrantLock> orderReentrantLockMap = new ConcurrentHashMap<>();
public static void signOrder(Long orderId, Runnable runnable) {
ReentrantLock o = null;
do {
//开始执行先unlock
if (o != null) {
o.unlock();
}
o = orderReentrantLockMap.computeIfAbsent(orderId, k -> new ReentrantLock());
//加锁
o.lock();
//判断是不是同一把锁,不是重新排队去拿锁
} while (o != orderReentrantLockMap.get(orderId));
try {
//执行业务
runnable.run();
} finally {
// 判断有没有排队执行的线程
if (o.getQueueLength() == 0) {
//误读 , 读取时没有线程等待拿锁,但删除时可能产生有相同订单已经进行排队拿锁等待执行 。这时while 语句解决了这个问题
orderReentrantLockMap.remove(orderId);
}
//释放锁
o.unlock();
}
}