Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/381.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避免在不相交集的情况下锁定_Java_Multithreading_Concurrency_Java.util.concurrent - Fatal编程技术网

Java避免在不相交集的情况下锁定

Java避免在不相交集的情况下锁定,java,multithreading,concurrency,java.util.concurrent,Java,Multithreading,Concurrency,Java.util.concurrent,我有一个这样的用例。我的一个方法将列表作为参数。当且仅当至少有一个对象已被其他线程锁定时,我需要保护关键部分。如何使用java.util.concurrent包实现?我可以想到简单的基于哈希表的解决方案, 差不多 class ContainsCriticalSections { HashTable<SomeObject, Thread> map; //shared by multiple threads someCriticalMethod(List<Some

我有一个这样的用例。我的一个方法将列表作为参数。当且仅当至少有一个对象已被其他线程锁定时,我需要保护关键部分。如何使用java.util.concurrent包实现?我可以想到简单的基于哈希表的解决方案, 差不多

class ContainsCriticalSections {
    HashTable<SomeObject, Thread> map; //shared by multiple threads

    someCriticalMethod(List<SomeObject> objects) {
        acquireLocks(objects);
        //do critical task
        releaseLocks(objects);
    }

    synchronized acquireLock(List<SomeObject> objects) {
        bool canLock = false;
        while (!canLock) {
               for (SomeObject obj : objects) {
                   if (!map.contains(obj)) {
                       canLock = true;   
                   }
                   else if(map.get(obj).equals(Thread.currentThread())) {// ensuring re-entrace
                       canLock = true; 
                   }
                   else {
                       canLock = false;    
                   }
               }
               if (!canLock) {
                   wait();
               }
        }
        for (SomeObject obj : objects) {
                   map.put(obj, Thread.currentThread());
        }   

    } 

    synchronized releaseLock(List<SomeObject> objects) {
            for (SomeObject obj : objects) {
                   map.reomve(obj);
            }
            notify();
    }

  }
类包含ScripticalSections{
哈希表映射;//由多个线程共享
someCriticalMethod(列出对象){
获取锁(对象);
//做关键任务
释放锁(对象);
}
同步的acquireLock(列出对象){
bool-canLock=false;
而(!canLock){
对于(SomeObject对象:对象){
如果(!map.contains(obj)){
canLock=true;
}
else if(map.get(obj).equals(Thread.currentThread()){//确保重入
canLock=true;
}
否则{
canLock=false;
}
}
如果(!canLock){
等待();
}
}
对于(SomeObject对象:对象){
put(obj,Thread.currentThread());
}   
} 
同步释放锁(列出对象){
对于(SomeObject对象:对象){
reomve地图(obj);
}
通知();
}
}
因此,在上述情况下,如果两个调用A、B、C和D、E、F不阻塞。但是,A,B,C和A,E,F会阻塞


但是,我强烈地感觉到这里会有一些既定的范例(使用java.util.Concurrent)。

您需要获取所有锁,否则,即使在您进入关键区域时,没有人持有任何锁,当您在里面时,也可能有人获取一个锁。以下是可用于在多个锁下运行任务的方法:

public static void runUnderMultipleLocks (Runnable task, Object ... monitors)
{
    runUnderMultipleLocks (task, 0, monitors);
}

private static void runUnderMultipleLocks (Runnable task, int offset, Object ... monitors)
{
    if (offset == monitors.length) task.run ();
    else
    {
        synchronized (monitors [offset])
        {
            runUnderMultipleLocks (task, offset + 1, monitors);
        }
    }
}

我怀疑您正在寻找
读写锁
。有关示例,请参见

读写
锁允许多个并发的
锁,但任何试图获得
锁的尝试都将被阻止,直到所有锁(
)都被释放


因此,采用
列表
的方法应该请求
写入
锁,而其他所有方法都请求
读取
锁。

@OldCurmudgeon…感谢您提供有关ReadWriteLock的信息。但是,这不符合我的目的。我试图实现的是典型的关键部分保护。@Gopal-你所说的典型是什么意思?对我来说,我对你的代码的解释很像一个
ReadWrite
锁。@OldCurmudgeon…很抱歉不清楚。我的意思是,我上面提到的关键部分只包含写操作,并且不是线程安全的。假设我想在缓存中更新(readAndIncrement)对象A、B、C(在单个批中)和D、E、F(在单个批中)。如果thread1尝试更新A、B、C,而thread2尝试更新D、E、F,则不存在任何问题,并且在一个线程中等待另一个线程完成也没有意义。但是,如果thread1尝试更新A、B、C,而thread2尝试更新A、D、E,那么就会出现问题,调用应该序列化。@Gopal-Ah!我懂了。这听起来像是你需要一个单独的读/写锁。也许你可以考虑任何一个S?别忘了在锁定之前对显示器进行分类。“排序”的意思可能是“按正确的顺序排列”,而不是“按升序/降序排列”。比方说,一个线程使用监视器(A、B、C)调用,另一个线程同时使用监视器(C、B、A)调用,即使没有B,也会死锁。