Concurrency: Cooperation Between Tasks (2)

4. Producer-Consumers and Queues

  java.util.concurrent.BlockingQueue接口定义了一种同步队列,同一时间只允许一个任务对队列进行插入和删除。BlockingQueue有多种标准实现,LinkedBlockingQueue提供不限长度的队列,ArrayBlockingQueue具有固定长度。如果队列为空,试图从该队列中获取元素的任务会被挂起,直到有新元素添加进队列。

上面的例子在main()中分别向三种BlockingQueue中依次加入5个LiftOffLiftOffLiftOffRunner消耗。同步由BlockingQueue处理,LiftOffRunner不需要考虑同步问题,

4.1. BlockingQueues of Toast

  下面是使用BlockingQueue的另一个例子:

四个任务分别负责烤面包、涂抹黄油、涂抹果酱和吃面包。各任务都没有使用同步,同步、任务的挂起和唤醒都由BlockingQueue实现。

5. Using pipes for I/O between tasks

  管道(Pipe)提供了任务间I/O的通信。任务可以通过PipedWriterPipedReader对管道进行写入和读取。管道类似于前面的阻塞队列。

Sender通过out = new PipedWriter()创建了PipedWriterReceiver通过in = new PipedReader(sender.getPipedWriter()),使用Senderout创建PipedReaderin.read()会在IO没有数据时自动进行阻塞,不需要手动使用sleep()wait()。从打印还可以看到,PipedReader可以被exec.shutdownNow()打断。