我有一种服务方法,基本上是将记录插入数据库。我试图实现的是基于对象或其变量来阻止一段代码。
我需要基于此ID阻止其他线程:rcvTransactionRequest.getPoDistributionId()
我不想阻止所有进入此方法的线程。最后,我试图验证不应超过的应收数量,如果有多个线程进入关键部分,可能会发生。
PoDistPayload poDistPayload = poDistService.getPoDist(rcvTransactionRequest.getPoDistributionId());
synchronized (poDistPayload) {
if (!poDistService.isReceivable(poDistPayload, rcvTransactionRequest.getQuantity()))
throw ebsExceptionFactory.build(1036L, rcvTransactionRequest.getQuantity(), poDistPayload.getReceivableQuantity());
PoDistRcv poDistRcv = PoDistRcv.of(rcvTransactionRequest);
poDistRcv.setStatus(Status.TRANSACTION_STARTED);
poDistRcv = poDistRcvRepository.save(poDistRcv);
return new BaseTransactionResponse(poDistRcv.getTransactionId(), serialCountPerRequest, poDistRcv.getStatus());
}
您可以使用ConcurrentMap来实现简单的锁定方案:
Object newLock=new Object();
Object existingLock;
// Wait until this thread can acquire lock
synchronized(newLock) {
do {
existingLock=cMap.putIfAbsent(distributionId,newLock);
if(existingLock!=null) {
// Locked by another thread. You can fail immediately, or wait until the lock is released
synchronized(existingLock) {
// Need timeout here because lock holder may notify before we wait
existingLock.wait(timeout);
}
}
} while(existingLock!=null);
// You have the lock
// Do work
// Unlock and notify
cMap.remove(distributionId,newLock);
newLock.notify();
}
我用番石榴条解决了问题。