在多线程java中,一对一的需求与统一的服务员需求一对一

时间:2016-08-09 18:27:44

标签: java multithreading concurrency

在解释多线程中的有界缓冲区示例时,以下术语是什么:

1.one-in,one-out requirements

2.统一服务员要求

我在书java concurrency in practice

中看到了以下陈述
BoundedBuffer meets the one-in, one-out requirement, but does not meet the uniform waiters requirement because waiting threads might be waiting for either the “not full” and “not empty” condition.

有人可以向我解释这两个术语及其区别。

由于

1 个答案:

答案 0 :(得分:2)

这些术语指的是wait()在任意监视器上的线程:

  • 统一服务员:等待的线程是“相等的”,即他们等待相同的条件变为真。
  • one-in,one-out :条件通知允许最多一个线程继续。

只有在满足两个属性时才应使用notify(),否则调用notifyAll()(虽然效率较低)。

Goetz在第303页解释了这一点并给出了两个具体的例子:

  

BoundedBuffer符合一进一出的要求,但不符合统一的服务员要求,因为等待的线程可能正在等待“不完整” [producer block] on put] 和“not empty” [消费者阻止采取] 条件“。一个”起始门“锁存器[...],其中单个事件释放一组线程,不符合一进一出的要求因为打开起始门允许多个线程继续

您还可以使用java.util.concurrent中的类来证明这一点:

BlockingQueue<String> queue = new ArrayBlockingQueue<>(1);

new Thread(() -> {
    try {
        TimeUnit.SECONDS.sleep(1L);
        System.out.println("Producer starts.");
        queue.put("foo");
    } catch (InterruptedException e) { /* NOP */ }
}).start();

try {
    System.out.println("Consumer starts.");
    System.out.println(queue.take());
} catch (InterruptedException e) { /* NOP */ }

消费者必须等到生产者将"foo"放入队列。两者都在等待不同的条件,因此,BlockingQueue不符合统一的服务员要求。

另一方面,CountDownLatch符合统一服务员的要求,但不符合一对一的要求。一旦锁存器达到零,所有等待的线程都被释放:

CountDownLatch latch = new CountDownLatch(1);
Runnable r = () -> {
    try {
        latch.await();
        System.out.println("Thread proceeds.");
    } catch (InterruptedException e) { /* NOP */ }
};

new Thread(r).start();
new Thread(r).start();

try {
    TimeUnit.SECONDS.sleep(1L);
    System.out.println("Count down.");
    latch.countDown();
} catch (InterruptedException e) { /* NOP */ }