简体   繁体   English

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

[英]Java avoid locking in case of disjoint sets

I have a use case like this. 我有一个像这样的用例。 One of my method takes a List as parameter. 我的一个方法将List作为参数。 I need to protect the critical section if and only if atleast one of the object is already locked by some other thread. 当且仅当对象的至少一个已经被某个其他线程锁定时,我需要保护关键部分。 How can achieve using java.util.concurrent package? 如何实现使用java.util.concurrent包? I can think of simple HashTable based solution, something like 我可以想到简单的基于HashTable的解决方案,例如

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();
    }

  }

So in the above case if two invocations with A,B,C and D, E, F don't block. 因此,在上述情况下,如果两个调用A,B,C和D,E,F不会阻塞。 But, A, B, C and A, E, F will block. 但是,A,B,C和A,E,F将阻止。

but, I strongly feel there will some established paradigm here (using java.util.Concurrent). 但是,我强烈认为这里会有一些既定的范例(使用java.util.Concurrent)。

You need to acquire all the locks, otherwise even if when you were entering critical section nobody was holding any locks, somebody may acquire one while you are inside. 你需要获得所有的锁,否则即使你进入临界区时没有人拿着任何锁,有人可能会在你进去的时候获得一把锁。 Here is method that can be used to run task under several locks: 这是可用于在多个锁下运行任务的方法:

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);
        }
    }
}

I suspect you are looking for a ReadWriteLock . 我怀疑你正在寻找一个ReadWriteLock See ReentrantReadWriteLock for an example. 有关示例,请参阅ReentrantReadWriteLock

A ReadWrite lock allows multiple concurrent Read locks but any attempt to obtain a Write lock will block until all locks ( Read or Write ) have been released. ReadWrite锁允许多个并发Read锁,但任何获取Write锁的尝试都将阻塞,直到释放所有锁( ReadWrite )。

So your method that takes the List should request a Write lock while all of the others request Read locks. 因此,获取List方法应该请求Write锁定,而其他所有请求Read锁定。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM