java 生产者与消费者问题
分别利用 锁、信号量、同步监视器实现了生产者消费者问题。
package thread; import java.util.Random; import java.util.concurrent.Semaphore; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; class Item { int id; public Item(int id) { this.id = id; } public String toString() { return "[item " + id + "]"; } } abstract class Buffer { int capacity; Item[] items; int count; int in, out; public Buffer(int capacity) { this.capacity = capacity; items = new Item[capacity]; count = 0; in = out = 0; } abstract void put(Item item); abstract Item get(); public void printBuf() { System.out.print("current buf status: [ "); for (int i = 0; i < capacity; i++) { System.out.print(items[i] + " "); } System.out.print("] "); System.out.print("count:" + count + " "); System.out.print("in:" + in + " out:" + out + " "); System.out.println(); } } /** * 利用锁实现线程同步的buffer * * @author jd * */ class LockBuffer extends Buffer { Lock lock = new ReentrantLock(); Condition empty = lock.newCondition(); Condition full = lock.newCondition(); public LockBuffer(int capacity) { super(capacity); } public void put(Item item) { lock.lock(); try { while (count == capacity) full.await(); items[in] = item; in = (in + 1) % capacity; count++; empty.signal(); System.out.println(Thread.currentThread().getName() + " put item " + item.id); printBuf(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } public Item get() { lock.lock(); Item res = null; try { while (count == 0) empty.await(); res = items[out]; items[out] = null; out = (out + 1) % capacity; count--; full.signal(); System.out.println(Thread.currentThread().getName() + " get item " + res.id); printBuf(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } return res; } } /** * 利用信号量实现的线程同步的buffer * * @author jd * */ class SemaphoreBuffer extends Buffer { Semaphore mutex; Semaphore full; Semaphore empty; public SemaphoreBuffer(int capacity) { super(capacity); mutex = new Semaphore(1); full = new Semaphore(0); empty = new Semaphore(capacity); } public void put(Item item) { try { empty.acquire(); mutex.acquire(); } catch (InterruptedException e) { e.printStackTrace(); } items[in] = item; in = (in + 1) % capacity; count++; System.out.println(Thread.currentThread().getName() + " put item " + item.id); printBuf(); mutex.release(); full.release(); } public Item get() { try { full.acquire(); mutex.acquire(); } catch (InterruptedException e) { e.printStackTrace(); } Item res = items[out]; items[out] = null; out = (out + 1) % capacity; count--; System.out.println(Thread.currentThread().getName() + " get item " + res.id); printBuf(); mutex.release(); empty.release(); return res; } } /** * 利用同步监视器实现的线程同步的buffer * * @author jd * */ class MonitorBuffer extends Buffer { public MonitorBuffer(int capacity) { super(capacity); } public void put(Item item) { synchronized (this) { try { while (count == capacity) wait(); } catch (InterruptedException e) { e.printStackTrace(); } items[in] = item; in = (in + 1) % capacity; count++; notifyAll(); System.out.println(Thread.currentThread().getName() + " put item " + item.id); printBuf(); } } public Item get() { synchronized (this) { try { while (count == 0) wait(); } catch (InterruptedException e) { e.printStackTrace(); } Item res = items[out]; items[out] = null; out = (out + 1) % capacity; count--; notifyAll(); System.out.println(Thread.currentThread().getName() + " get item " + res.id); printBuf(); return res; } } } class Producer implements Runnable { Buffer buf; Random rand = new Random(); public Producer(Buffer buf) { this.buf = buf; } public void run() { for (int i = 0; i < 10; i++) { Item item = new Item(rand.nextInt(100)); buf.put(item); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } } } class Consumer implements Runnable { Buffer buf; public Consumer(Buffer buf) { this.buf = buf; } public void run() { for (int i = 0; i < 10; i++) { Item item = buf.get(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } public class BoundedBufferTest { public static void main(String[] args) { // Buffer buf = new LockBuffer(5); // Buffer buf = new SemaphoreBuffer(5); Buffer buf = new MonitorBuffer(5); // 3个生产者,3个消费者,每个生产或者消费10次。 for (int i = 0; i < 3; i++) { new Thread(new Producer(buf), "p" + i).start(); new Thread(new Consumer(buf), "c" + i).start(); } } }