對于多線程程序來說,不管任何編程語言,生產(chǎn)者和消費(fèi)者模型都是最經(jīng)典的。就像學(xué)習(xí)每一門編程語言一樣,Hello World!都是最經(jīng)典的例子。實(shí)際上,準(zhǔn)確說應(yīng)該是“生產(chǎn)者-消費(fèi)者-倉儲”模型,離開了倉儲,生產(chǎn)者消費(fèi)者模型就顯得沒有說服力了。對于此模型,應(yīng)該明確一下幾點(diǎn):1、生產(chǎn)者僅僅在倉儲未滿時(shí)候生產(chǎn),倉滿則停止生產(chǎn)。2、消費(fèi)者僅僅在倉儲有產(chǎn)品時(shí)候才能消費(fèi),倉空則等待。3、當(dāng)消費(fèi)者發(fā)現(xiàn)倉儲沒產(chǎn)品可消費(fèi)時(shí)候會通知生產(chǎn)者生產(chǎn)。4、生產(chǎn)者在生產(chǎn)出可消費(fèi)產(chǎn)品時(shí)候,應(yīng)該通知等待的消費(fèi)者去消費(fèi)。

package cn.thread;import java.util.concurrent.BlockingQueue;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.LinkedBlockingQueue;/** * java多線程模擬生產(chǎn)者消費(fèi)者問題 * * PRoducerConsumer是主類,Producer生產(chǎn)者,Consumer消費(fèi)者,Product產(chǎn)品,Storage倉庫 * * @author 林計(jì)欽 * @version 1.0 2013-7-24 下午04:49:02 */public class ProducerConsumer { public static void main(String[] args) { ProducerConsumer pc = new ProducerConsumer(); Storage s = pc.new Storage(); ExecutorService service = Executors.newCachedThreadPool(); Producer p = pc.new Producer("張三", s); Producer p2 = pc.new Producer("李四", s); Consumer c = pc.new Consumer("王五", s); Consumer c2 = pc.new Consumer("老劉", s); Consumer c3 = pc.new Consumer("老林", s); service.submit(p); //service.submit(p2); service.submit(c); service.submit(c2); service.submit(c3); } /** * 消費(fèi)者 * * @author 林計(jì)欽 * @version 1.0 2013-7-24 下午04:53:30 */ class Consumer implements Runnable { private String name; private Storage s = null; public Consumer(String name, Storage s) { this.name = name; this.s = s; } public void run() { try { while (true) { System.out.println(name + "準(zhǔn)備消費(fèi)產(chǎn)品."); Product product = s.pop(); System.out.println(name + "已消費(fèi)(" + product.toString() + ")."); System.out.println("==============="); Thread.sleep(500); } } catch (InterruptedException e) { e.printStackTrace(); } } } /** * 生產(chǎn)者 * * @author 林計(jì)欽 * @version 1.0 2013-7-24 下午04:53:44 */ class Producer implements Runnable { private String name; private Storage s = null; public Producer(String name, Storage s) { this.name = name; this.s = s; } public void run() { try { while (true) { Product product = new Product((int) (Math.random() * 10000)); // 產(chǎn)生0~9999隨機(jī)整數(shù) System.out.println(name + "準(zhǔn)備生產(chǎn)(" + product.toString() + ")."); s.push(product); System.out.println(name + "已生產(chǎn)(" + product.toString() + ")."); System.out.println("==============="); Thread.sleep(500); } } catch (InterruptedException e1) { e1.printStackTrace(); } } } /** * 倉庫,用來存放產(chǎn)品 * * @author 林計(jì)欽 * @version 1.0 2013-7-24 下午04:54:16 */ public class Storage { BlockingQueue<Product> queues = new LinkedBlockingQueue<Product>(10); /** * 生產(chǎn) * * @param p * 產(chǎn)品 * @throws InterruptedException */ public void push(Product p) throws InterruptedException { queues.put(p); } /** * 消費(fèi) * * @return 產(chǎn)品 * @throws InterruptedException */ public Product pop() throws InterruptedException { return queues.take(); } } /** * 產(chǎn)品 * * @author 林計(jì)欽 * @version 1.0 2013-7-24 下午04:54:04 */ public class Product { private int id; public Product(int id) { this.id = id; } public String toString() {// 重寫toString方法 return "產(chǎn)品:" + this.id; } }}
新聞熱點(diǎn)
疑難解答
圖片精選