在 Java 中实现阻塞函数调用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7735328/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 21:12:15  来源:igfitidea点击:

Implement a blocking function call in Java

javaconcurrencyblocking

提问by mikera

What is the recommended / best way to implement a blocking function call in Java, that can be later unblocked by a call from another thread?

在 Java 中实现阻塞函数调用的推荐/最佳方法是什么,稍后可以通过来自另一个线程的调用解除阻塞?

Basically I want to have two methods on an object, where the first call blocks any calling thread until the second method is run by another thread:

基本上我想在一个对象上有两个方法,第一个调用阻止任何调用线程,直到第二个方法由另一个线程运行:

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() {
     // ...
  }

} 

The intention BTW is not just to get blocking behaviour, but to write a method that blocks until some future point when it is possible to compute the required result.

顺便说一句,意图不仅仅是获得阻塞行为,而是编写一个方法,该方法阻塞直到可以计算所需结果的某个未来点。

回答by Simon Nickerson

You can use a CountDownLatch.

您可以使用CountDownLatch

latch = new CountDownLatch(1);

To block, call:

要阻止,请致电:

latch.await();

To unblock, call:

要解除封锁,请致电:

latch.countDown();

回答by Brendan Long

If you're waiting on a specific object, you can call myObject.wait()with one thread, and then wake it up with myObject.notify()or myObject.notifyAll(). You may need to be inside a synchronizedblock:

如果你正在等待一个特定的对象,你可以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();
        }
    }
}

回答by Brian Kelly

There are a couple of different approaches and primitives available, but the most appropriate sounds like a CyclicBarrieror a CountDownLatch.

有几种不同的方法和原语可用,但最合适的听起来像CyclicBarrierCountDownLatch