Java Reference
In-Depth Information
merely putting it in her mailbox and hoping she gets it soon. Since a SynchronousQueue
has no storage capacity, put and take will block unless another thread is already waiting
to participate in the handoff. Synchronous queues are generally suitable only when there are
enough consumers that there nearly always will be one ready to take the handoff.
5.3.1. Example: Desktop Search
One type of program that is amenable to decomposition into producers and consumers is an
agent that scans local drives for documents and indexes them for later searching, similar to
Google Desktop or the Windows Indexing service. DiskCrawler in Listing 5.8 shows a
producer task that searches a file hierarchy for files meeting an indexing criterion and puts
their names on the work queue; Indexer in Listing 5.8 shows the consumer task that takes
file names from the queue and indexes them.
The producer-consumer pattern offers a thread-friendly means of decomposing the desktop
search problem into simpler components. Factoring file-crawling and indexing into separate
activities results in code that is more readable and reusable than with a monolithic activity
that does both; each of the activities has only a single task to do, and the blocking queue
handles all the flow control, so the code for each is simpler and clearer.
The producer-consumer pattern also enables several performance benefits. Producers and
consumers can execute concurrently; if one is I/O-bound and the other is CPU-bound, ex-
ecuting them concurrently yields better overall throughput than executing them sequentially.
If the producer and consumer activities are parallelizable to different degrees, tightly coup-
ling them reduces parallelizability to that of the less parallelizable activity.
Listing 5.9 starts several crawlers and indexers, each in their own thread. As written, the con-
sumer threads never exit, which prevents the program from terminating; we examine several
techniques for addressing this problem in Chapter 7 . While this example uses explicitly man-
aged threads, many producer-consumer designs can be expressed using the Executor task
execution framework, which itself uses the producer-consumer pattern.
5.3.2. Serial Thread Confinement
The blocking queue implementations in java.util.concurrent all contain sufficient
internal synchronization to safely publish objects from a producer thread to the consumer
thread.
Search WWH ::




Custom Search