Реализовать блокировку вызова функции в Java - PullRequest
9 голосов
/ 12 октября 2011

Каков рекомендуемый / лучший способ реализовать вызов функции блокировки в Java, который впоследствии может быть разблокирован вызовом из другого потока?

По сути, я хочу иметь два метода для объекта, где первый вызов блокирует любой вызывающий поток, пока второй метод не будет запущен другим потоком:

public class Blocker {

  /* Any thread that calls this function will get blocked */
  public static SomeResultObject blockingCall() {
     // ...      
  }

  /* when this function is called all blocked threads will continue */
  public void unblockAll() {
     // ...
  }

} 

Намерение, кстати, не просто получить поведение блокировки, но написать метод, который блокирует до некоторой будущей точки, когда возможно вычислить требуемый результат.

Ответы [ 3 ]

13 голосов
/ 12 октября 2011

Вы можете использовать CountDownLatch .

latch = new CountDownLatch(1);

Чтобы заблокировать, позвоните:

latch.await();

Чтобы разблокировать, позвоните:

latch.countDown();
3 голосов
/ 12 октября 2011

Если вы ожидаете определенного объекта, вы можете вызвать myObject.wait() одним потоком, а затем разбудить его с помощью myObject.notify() или myObject.notifyAll(). Вам может понадобиться быть внутри synchronized блока:

class Example {

    List list = new ArrayList();

    // Wait for the list to have an item and return it
    public Object getFromList() {
        synchronized(list) {
            // Do this inside a while loop -- wait() is
            // not guaranteed to only return if the condition
            // is satisfied -- it can return any time
            while(list.empty()) {
                // Wait until list.notify() is called
                // Note: The lock will be released until
                //       this call returns.
                list.wait();
            }
            return list.remove(0);
        }
    }

    // Add an object to the list and wake up
    // anyone waiting
    public void addToList(Object item) {
        synchronized(list) {
            list.add(item);
            // Wake up anything blocking on list.wait() 
            // Note that we know that only one waiting
            // call can complete (since we only added one
            // item to process. If we wanted to wake them
            // all up, we'd use list.notifyAll()
            list.notify();
        }
    }
}
2 голосов
/ 12 октября 2011

Существует несколько различных подходов и примитивов, но наиболее подходящие звуки, такие как CyclicBarrier или CountDownLatch .

...