A promising API addition in J2SE 5.0 is the concurrency library of classes, located in the package java.util.concurrent. It provides utility classes to help you solve many of the issues surrounding multithreading. While you should prefer use of this library, its existence doesn't mean that you don't need to learn the fundamentals and concepts behind threading.[11]
Since queues are such a useful construct in multithreaded applications, the concurrency library defines an interface, BlockingQueue, along with five specialized queue classes that implement this interface. Blocking queues implement another new interface, java.util.Queue, which defines queue semantics for collections. Blocking queues add concurrency-related capabilities to queues. Examples include the ability to wait for elements to exist when retrieving the next in line and the ability to wait for space to exist when storing elements. You can rework the Server class to use a LinkedBlockingQueue instead of a LinkedList. package sis.search; import java.util.concurrent.*; public class Server extends Thread { private BlockingQueue<Search> queue = new LinkedBlockingQueue<Search>(); private ResultsListener listener; public Server(ResultsListener listener) { this.listener = listener; start(); } public void run() { while (true) try { execute(queue.take()); } catch (InterruptedException e) { } } public void add(Search search) throws Exception { queue.put(search); } private void execute(Search search) { search.execute(); listener.executed(search); } } The LinkedBlockingQueue method put adds an element to the end of the queue. The take method removes an element from the beginning of the queue. It also waits until an element is available in the queue. The code doesn't look very different from your original implementation of Server, but it is now thread-safe. |