問題描述:一個倉庫可以存放N件物品。生產者每生產一件產品,將產品放入倉庫,倉庫滿了就停止生產。消費者每次從倉庫中去一件物品,然后進行消費,倉庫空時就停止消費。
???解答:在J2SE1.5中的java.util.concurrent?新功能包提供一些實用的通用類供并行程序使用。其中的BlockingQueue接口及其實現類對于解決[生產者-消費者問題]非常方便。下面是實現的代碼(例子摘抄自jdk1.5幫助文檔,稍做修改):
import?java.util.concurrent.ArrayBlockingQueue;
import?java.util.concurrent.BlockingQueue;
/**
?*?@author?Rebirth
?*/
class?Consumer?implements?Runnable?{
?private?int?i=0;
?private?String?sName="";
?private?final?BlockingQueue?queue;
?Consumer(BlockingQueue?q,String?sName)?{?queue?=?q;this.sName=sName;?}
?/*?
??*?@see?java.lang.Runnable#run()
??*/
?public?void?run()?{
??while(i<5)?{?
???try{
????//消費產品
????consume(queue.take());??????????
?????????}
???catch?(InterruptedException?ex)?{
????System.out.println(ex.getMessage());
???}
???finally{i++;}
??}
?}
?private?void?consume(Object?product){
??System.out.println(sName?+?"?consume?"?+?product.toString());
?}
}
class?Producer?implements?Runnable?{
?private?int?i=0;
?private?String?sName="";?
?private?int?iNum=0;
?private?final?BlockingQueue?queue;
?Producer(BlockingQueue?q,String?sName)?{?queue?=?q;this.sName=sName;?}
?/*?(non-Javadoc)
??*?@see?java.lang.Runnable#run()
??*/
?public?void?run()?{
??while(i<10)?{?
???try{
????//生產產品
????queue.put(produce());?????????????
??????}catch?(InterruptedException?ex)?{
????System.out.println(ex.getMessage());
??????}finally{i++;}
??}??????
?}
?private?Object?produce(){
??String?sProduct?="p"?+?(++iNum);
??System.out.println(sName?+?"?product?"?+?sProduct);??
??return?sProduct;
?}
}
public?class?Factory?{
??public?static?void?main(String[]?args)?{
??????BlockingQueue?q?=?new?ArrayBlockingQueue(10);
??????Producer?p?=?new?Producer(q,"?p1?");
??????Consumer?c1?=?new?Consumer(q,"?c1?");
??????Consumer?c2?=?new?Consumer(q,"?c2?");
??????new?Thread(p).start();
??????new?Thread(c1).start();
??????new?Thread(c2).start();??????
????}
}
???????BlockingQueue是線程安全的,當倉庫中已經沒有物品而消費者繼續往里面取時隊列自動進行阻塞。需要注意的是,BlockingQueue是不接受null值的,但嘗試將一個null值插入隊列,會拋出NullPointerException?例外。
凡是有該標志的文章,都是該blog博主Caoer(草兒)原創,凡是索引、收藏
、轉載請注明來處和原文作者。非常感謝。