在实例对象上同步

问题描述 投票:0回答:2

我有一种服务方法,基本上是将记录插入数据库。我试图实现的是基于对象或其变量来阻止一段代码。

我需要基于此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());
    }
java multithreading synchronized
2个回答
0
投票

您可以使用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();
}

0
投票

我用番石榴条解决了问题。

© www.soinside.com 2019 - 2024. All rights reserved.