I found very interesting and nice blocking queue implementation.
Off course you can use Java BlockingQueue (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html) implementation,
but if you want to learn something new along the way why not implement it by yourself?
I left some original comments and add some of my own.
Enjoy!
Off course you can use Java BlockingQueue (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html) implementation,
but if you want to learn something new along the way why not implement it by yourself?
I left some original comments and add some of my own.
Enjoy!
public class BlockingQueueTest { private final BlockingQ bq = new BlockingQ(); /** The Worker thread is not very robust. If a RuntimeException occurse in the run method, the thread will stop. */ private class Worker extends Thread { public Worker(String name) { super(name); start(); } public void run() { try { //This loop will continue to take next runnable task from queue or //will block on pop() method. while(!isInterrupted()) { ((Runnable)bq.pop()).run(); } //This will spit out the "poison pill". :) } catch(InterruptedException ex) {} System.out.println(getName() + " finished"); } } public BlockingQueueTest() { // We create 10 threads as workers Thread[] workers = new Thread[10]; for (int i=0; i < workers.length; i++) workers[i] = new Worker("Worker Thread " + i); // We then push 100 commands onto the queue for (int i=0; i<100; i++) { final String msg = "Task " + i + " completed"; bq.push(new Runnable() { public void run() { System.out.println(msg); // Sleep a random amount of time, up to 1 second try { Thread.sleep((long)(Math.random()*1000)); } catch(InterruptedException ex) { } } }); } // We then push one "poison pill" onto the queue for each // worker thread, which will only be processed once the other // tasks are completed. for (int i=0; i < workers.length; i++) { bq.push(new Runnable() { public void run() { Thread.currentThread().interrupt(); } }); } // Lastly we join ourself to each of the Worker threads, so // that we only continue once all the worker threads are // finished. for (int i=0; i < workers.length; i++) { try { workers[i].join(); } catch(InterruptedException ex) {} } System.out.println("BlockingQueueTest finished"); } public static void main(String[] args) throws Exception{ new BlockingQueueTest(); } } class BlockingQ { /** It makes logical sense to use a linked list for a FIFO queue, although an ArrayList is usually more efficient for a short queue (on most VMs). */ private final LinkedList queue = new LinkedList(); /** This method pushes an object onto the end of the queue, and then notifies one of the waiting threads. */ public void push(Object o) { synchronized(queue) { queue.add(o); //This will notify blocked thread (on queue.wait() bellow) to continue. queue.notify(); } } /** The pop operation blocks until either an object is returned or the thread is interrupted, in which case it throws an InterruptedException. */ public Object pop() throws InterruptedException { //Racing condition starts here. synchronized(queue) { //Thread will wait if queue is empty. while (queue.isEmpty()) { queue.wait(); } return queue.removeFirst(); } } }This implementation was taken from: http://www.javaspecialists.eu/archive/Issue016.html
No comments:
Post a Comment