Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/398.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ReentrantLock unlock抛出Java.lang.IllegalMonitorStateException_Java_Multithreading_Asynchronous_Concurrency_Locking - Fatal编程技术网

Java ReentrantLock unlock抛出Java.lang.IllegalMonitorStateException

Java ReentrantLock unlock抛出Java.lang.IllegalMonitorStateException,java,multithreading,asynchronous,concurrency,locking,Java,Multithreading,Asynchronous,Concurrency,Locking,线程在执行之前需要获取多个锁,因此我将所有锁放入一个列表中,并迭代tryLock()调用它们,如果tryLock()成功,我将获取的锁添加到一个名为acquiredLocks的列表中,因此当任何锁'tryLock()失败时,我可以解锁已经获取的锁, 但是当回滚发生时,它会通过ReentrantLock抛出java.lang.IllegalMonitorStateException,因为锁不是由当前线程持有的。我检查了acquiredLocks列表,其中的一些锁确实是由另一个线程获取的,但是我在将

线程在执行之前需要获取多个锁,因此我将所有锁放入一个列表中,并迭代tryLock()调用它们,如果tryLock()成功,我将获取的锁添加到一个名为acquiredLocks的列表中,因此当任何锁'tryLock()失败时,我可以解锁已经获取的锁, 但是当回滚发生时,它会通过ReentrantLock抛出java.lang.IllegalMonitorStateException,因为锁不是由当前线程持有的。我检查了acquiredLocks列表,其中的一些锁确实是由另一个线程获取的,但是我在将其添加到acquiredLocks列表之前调用了tryLock()

private final List<Lock> locks = new CopyOnWriteArrayList<>();
private final List<Lock> acquiredLocks = new CopyOnWriteArrayList<>();


/**
  * try to acquire all locks, if any lock is not acquired, roll back and release all already acquired 
  * locks
  */
private boolean tryAllLocks() {
        for (Lock lock : locks) {
            if (lock.tryLock()) {
                acquiredLocks.add(lock);
            } else {
                acquiredLocks.forEach(Lock::unlock);
                return false;
            }
        }
        return true;
}

 public PriceGenerationAggregate call() throws Exception {
        try {
            if (TenorConst.isSpotTenor(marketPriceCache.getTenor())) {
                this.priceGenerationAggregate = new SpotRootPriceGenerationAggregate(marketPriceCache, synchronizeForwardSpotPrice());
            } else {
                this.priceGenerationAggregate = new ForwardRootPriceGenerationAggregate(marketPriceCache);
            }

            for (GenerationProduct generationProduct : priceGenerationAggregate.getAllSubscribedPriceForPriceGeneration().getAllGenerationProducts()) {
                Lock lock = ProductLockCache.getLock(generationProduct.getCcyPair(), generationProduct.getTenor(), generationProduct.getVolume());
                locks.add(lock);
            }
            // try all the locks before the price generation
            while (!tryAllLocks()) {
                Thread.sleep(100);
            }

            generatePrices();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            releaseAllLocks();
        }

        return priceGenerationAggregate;
    }
private final List locks=new CopyOnWriteArrayList();
private final List acquiredLocks=新建CopyOnWriteArrayList();
/**
*尝试获取所有锁,如果未获取任何锁,则回滚并释放所有已获取的锁
*锁
*/
私有布尔tryallocks(){
用于(锁定:锁定){
if(lock.tryLock()){
acquiredLocks.add(锁);
}否则{
acquiredLocks.forEach(Lock::unlock);
返回false;
}
}
返回true;
}
public PriceGenerationAggregate调用()引发异常{
试一试{
if(TenorConst.isSpotTenor(marketPriceCache.getTenor()){
this.priceGenerationAggregate=新的SpotRootPriceGenerationAggregate(marketPriceCache,synchronizeForwardSpotPrice());
}否则{
this.priceGenerationAggregate=新的ForwardRootPriceGenerationAggregate(marketPriceCache);
}
for(GenerationProduct GenerationProduct:priceGenerationAggregate.getAllSubscribedPriceForPriceGeneration().getAllGenerationProducts()){
Lock Lock=ProductLockCache.getLock(generationProduct.getCcyPair(),generationProduct.getTenor(),generationProduct.getVolume());
锁。添加(锁);
}
//在生成价格之前尝试所有锁
而(!tryallocks()){
睡眠(100);
}
生成许可证();
}捕获(例外e){
e、 printStackTrace();
}最后{
释放所有锁();
}
返回价格生成聚合;
}

解锁后,您忘记清除已获取锁的列表。解锁后,它们不再被获取,其他线程可以锁定它们:正如您所提到的,您看到来自
acquiredLocks
的锁被其他线程持有

添加一个
acquiredLocks.clear()语句(这仅在假定
acquiredLocks
每个线程都有一个新的列表实例的情况下有效)

private boolean tryallocks(){
用于(锁定:锁定){
if(lock.tryLock()){
acquiredLocks.add(锁);
}否则{
acquiredLocks.forEach(Lock::unlock);

acquiredLocks.clear();//解锁后,您忘记清除已获取锁的列表。解锁后,它们不再被获取,其他线程可以锁定它们:正如您所提到的,您看到来自
acquiredLocks
的锁被其他线程持有

解锁后添加一个
acquiredLocks.clear();
语句(这仅在假定
acquiredLocks
每个线程都有一个新的列表实例的情况下有效)

private boolean tryallocks(){
用于(锁定:锁定){
if(lock.tryLock()){
acquiredLocks.add(锁);
}否则{
acquiredLocks.forEach(Lock::unlock);

acquiredLocks.clear();//多个线程同时调用了
tryallocks
吗?如果是这样,那么您在线程之间共享
acquiredLocks
。如果这不是问题,或者只是问题的一部分,那么请注意,我也没有看到您清除
acquiredLocks
。acquiredLocks是每个线程的新实例,而不是sharedIs
tryAllLocks
由多个线程同时调用?如果是这样,那么您在线程之间共享
acquiredLocks
。如果这不是问题,或者只是问题的一部分,那么请注意,我也没有看到您清除
acquiredLocks
。acquiredLocks是每个线程的新实例,它不是共享的。我认为这就是问题的一部分,尽管如此ugh acquiredLocks是每个线程的一个新实例,锁在every while循环中添加到acquiredLocks,谢谢。我会在office tmr尝试修复它,我想就是这样,虽然acquiredLocks是每个线程的一个新实例,但是锁在every while循环中添加到acquiredLocks,谢谢。我会在office tmr尝试修复它
private boolean tryAllLocks() {
    for (Lock lock : locks) {
        if (lock.tryLock()) {
            acquiredLocks.add(lock);
        } else {
            acquiredLocks.forEach(Lock::unlock);
            acquiredLocks.clear(); // <-- added
            return false;
        }
    }
    return true;
}