1. 程式人生 > >juc包中BlockingQueue的生產者消費者示例

juc包中BlockingQueue的生產者消費者示例

/*
*Usage example, based on a typical producer-consumer scenario.
*Note that a <tt>BlockingQueue</tt> can safely be used with multiple
*producers and multiple consumers.
<pre name="code" class="java">*/
class Producer implements Runnable { private final BlockingQueue queue; Producer(BlockingQueue q) { queue = q; } public void run() { try { while (true) { queue.put(produce()); } } catch (InterruptedException ex) { ... handle ...} } Object produce() { ... }}class Consumer implements Runnable { private final BlockingQueue queue; Consumer(BlockingQueue q) { queue = q; } public void run() { try { while (true) { consume(queue.take()); } } catch (InterruptedException ex) { ... handle ...} } void consume(Object x) { ... }}class Setup { void main() { BlockingQueue q = new SomeQueueImplementation(); Producer p = new Producer(q); Consumer c1 = new Consumer(q); Consumer c2 = new Consumer(q); new Thread(p).start(); new Thread(c1).start(); new Thread(c2).start(); }}

撇開其鎖的具體實現,其流程就是我們在作業系統課上學習到的標準生產者模式,看來那些枯燥的理論還是有用武之地的。其中,最核心的還是Java的鎖實現,有興趣的朋友可以再進一步深究一下

LinkedBlockingQueue的具體實現

public void put(E e) throws InterruptedException {  
    if (e == null) throw new NullPointerException();  
    int c = -1;  
    final ReentrantLock putLock = this.putLock;  
    final AtomicInteger count = this.count;  
    putLock.lockInterruptibly();  
    try {  
        try {  
            while (count.get() == capacity)  
                notFull.await();  
        } catch (InterruptedException ie) {  
            notFull.signal(); // propagate to a non-interrupted thread  
            throw ie;  
        }  
        insert(e);  
        c = count.getAndIncrement();  
        if (c + 1 < capacity)  
            notFull.signal();  
    } finally {  
        putLock.unlock();  
    }  
    if (c == 0)  
        signalNotEmpty();  
}