http://www.cnblogs.com/zyp4614/p/6033757.html
今天寫的是最經典的生產者消費者問題,最簡單的版本,即只有一個緩沖區,緩沖區中只能放一個物品,即不考慮互斥關系。
問題簡單分析: 生產者在緩沖區為空的時候可以往緩沖區中放產品,消費者可以在緩沖區不空(即緩沖區中有產品時)可以取一個產品。
首先可以確定有兩個信號量
第一個信號量,是緩沖區是否空,當空的時候生產者可以放入產品,初值為1,因為默認緩沖區是空的
第二個信號量,是緩沖區是否滿,當滿的時候消費者可以取出產品,初值為0,因為開始緩沖區內沒有產品
/** * 代表緩沖區是否空 */ Semaphore empty; /** * 代表緩沖區是否滿 */ Semaphore full;
生產者偽代碼如下
wait(empty) //放入產品 signal(full)
消費者偽代碼如下:
wait(full) //取產品 signal(empty)
類實現如下
public class ProductAndVistor { Thread producer = new Thread(new Runnable() { @Override public void run() { String className = "producer"; // TODO Auto-generated method stub while(true) { Semaphore.Wait(empty, className); System.out.println(className + "往緩沖區放了一個產品"); //隨機生成休眠時間,代表放入產品的操作時間 long millis = (long) (Math.random() * 1000); try { Thread.sleep(millis); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } Semaphore.Signal(full, className); } } }); Thread vistor = new Thread(new Runnable() { String className = "vistor"; @Override public void run() { // TODO Auto-generated method stub while(true) { Semaphore.Wait(full, className); System.out.println(className + "從緩沖區取了一個產品"); long millis = (long) (Math.random() * 1000); try { Thread.sleep(millis); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } Semaphore.Signal(empty, className); } } }); /** * 代表緩沖區是否滿 */ Semaphore empty; /** * 代表緩沖區是否空 */ Semaphore full; public ProductAndVistor(Semaphore s1, Semaphore s2) { this.empty = s1; this.full = s2; } public ProductAndVistor() { empty = new Semaphore(1); full = new Semaphore(0); } public void start() { producer.start(); vistor.start(); } }