多线程终极模式:生产者-消费者模式
多線程de小事情
導(dǎo)航不迷路:文章目錄
- 多線程de小事情
- 前言
- 生產(chǎn)者-消費(fèi)者模式小科普
- 一、何為生產(chǎn)者
- 二、何為消費(fèi)者
- 三、緩沖區(qū)
- 設(shè)置緩沖區(qū)的三大優(yōu)點(diǎn):
- 代碼
- 總結(jié)
- 隨便說(shuō)說(shuō):
前言
在多線程中,我們經(jīng)常需要多個(gè)線程并發(fā)與協(xié)作,簡(jiǎn)稱(chēng)線程并發(fā)協(xié)作;
那么我們就要了解一個(gè)非常經(jīng)典的一個(gè)線程并發(fā)模式:生產(chǎn)者-消費(fèi)者模式;
生產(chǎn)者-消費(fèi)者模式小科普
一、何為生產(chǎn)者
生產(chǎn)者就是負(fù)責(zé)生產(chǎn)數(shù)據(jù)的模塊(該模塊可以是對(duì)象、方法、進(jìn)程或是線程)
二、何為消費(fèi)者
消費(fèi)者就是負(fù)責(zé)處理數(shù)據(jù)的模塊(該模塊可以是對(duì)象、方法、進(jìn)程或是線程)
三、緩沖區(qū)
緩沖區(qū)是生產(chǎn)者-消費(fèi)者模式的重要組成部分(核心);相當(dāng)一個(gè)“容器”,生產(chǎn)者生產(chǎn)數(shù)據(jù)后會(huì)放入緩沖區(qū),消費(fèi)者會(huì)從緩沖區(qū)內(nèi)取需要處理的數(shù)據(jù);
看到這里可能就有同學(xué)會(huì)問(wèn)了,生產(chǎn)者直接將生產(chǎn)的數(shù)據(jù)交給消費(fèi)者不就好了嗎?
為什么還弄的緩沖區(qū),怪麻煩的!
那我們就要看看,緩沖區(qū)的優(yōu)點(diǎn)了:
設(shè)置緩沖區(qū)的三大優(yōu)點(diǎn):
1.通過(guò)緩存可以實(shí)現(xiàn)并發(fā)協(xié)作
生產(chǎn)者只需要將生產(chǎn)的數(shù)據(jù)放入緩沖區(qū)內(nèi),不需要考慮消費(fèi)者的消費(fèi)狀況;同理消費(fèi)者只需要從緩沖區(qū)內(nèi)拿需要處理的數(shù)據(jù),不需要考慮生產(chǎn)者的生產(chǎn)情況;這樣就實(shí)現(xiàn)了生產(chǎn)者與消費(fèi)者的分離;
2.解耦生產(chǎn)者與消費(fèi)者
生產(chǎn)者不需要與消費(fèi)者直接打交道;
3.解決忙閑不均,提高效率
當(dāng)生產(chǎn)者效率低下的時(shí)候,緩沖區(qū)仍有數(shù)據(jù),不會(huì)影響消費(fèi)者的消費(fèi);當(dāng)消費(fèi)者消費(fèi)低下時(shí)生產(chǎn)者仍可以將生產(chǎn)的數(shù)據(jù)放入緩沖區(qū);從而避免了互相等待,提高效率;
千篇文章,不如代碼一行;
代碼
商品類(lèi)
package sx2; /*** 商品類(lèi),包括商品品牌和名稱(chēng)屬性;* */ public class Commodity1 {private String brand;private String name;public String getBrand() {return brand;}public void setBrand(String brand) {this.brand = brand;}public String getName() {return name;}public void setName(String name) {this.name = name;} }倉(cāng)庫(kù)類(lèi)(緩沖區(qū))
package sx2; /*** 倉(cāng)庫(kù)類(lèi),相當(dāng)于緩沖區(qū);* 包括商品屬性,以及進(jìn)庫(kù),和出庫(kù)的方法;* */ public class Warehouse1 {private Commodity1 commodity1;private boolean has;//判斷倉(cāng)庫(kù)是否有商品public Warehouse1(Commodity1 commodity1) {this.commodity1 = commodity1;}public Warehouse1() {} // 入庫(kù)與出庫(kù)的方法 判斷倉(cāng)庫(kù)是否有商品,有就出庫(kù),沒(méi)有入庫(kù)public synchronized void set(String brand,String name) {if(has) {try {wait();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}commodity1.setBrand(brand);try {Thread.sleep(300);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}commodity1.setName(name);System.out.println("入庫(kù):"+commodity1.getBrand()+commodity1.getName());notify();has=true;}public synchronized void get() {if(!has) {try {wait();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}System.out.println("出庫(kù):"+commodity1.getBrand()+commodity1.getName());notify();has=false;}}生產(chǎn)類(lèi)
package sx2; /*** 生產(chǎn)者類(lèi) * */ public class Producter1 implements Runnable{private Warehouse1 warehouse1;public Producter1() {// TODO Auto-generated constructor stub}public Producter1 (Warehouse1 warehouse1){this.warehouse1 = warehouse1;}// 生產(chǎn)十次,奇數(shù)時(shí)生產(chǎn)一種商品,偶數(shù)時(shí)生產(chǎn)另一種商品@Overridepublic void run() {for(int i=0;i<10;i++) {if(i%2==0) {warehouse1.set("東北","凍梨"+i);}else {warehouse1.set("海南", "小芭蕉"+i);}}}}消費(fèi)類(lèi)
package sx2; /*** 消費(fèi)類(lèi)* */ public class Customer1 implements Runnable{private Warehouse1 warehouse1;public Customer1() {}public Customer1(Warehouse1 warehouse1) {this.warehouse1 = warehouse1;} // 消費(fèi)十次@Overridepublic void run() {for(int i=0;i<10;i++) {warehouse1.get();}} }測(cè)試類(lèi)
package sx2;public class TestSX1 {public static void main(String[] args) {Commodity1 commodity1 = new Commodity1();Warehouse1 warehouse1 = new Warehouse1(commodity1);Producter1 p = new Producter1(warehouse1);Customer1 c = new Customer1(warehouse1);Thread t = new Thread(p);Thread t1 = new Thread(c);t1.start();t.start();}}效果圖
總結(jié)
線程并發(fā)協(xié)作也叫做線程通訊;一般用于生產(chǎn)者-消費(fèi)者模式:
1、生產(chǎn)者線程與消費(fèi)者線程共享同一個(gè)資源,并且互相依賴(lài),互為條件;
2、在生產(chǎn)者線程的角度,再?zèng)]有生產(chǎn)之前,需要消費(fèi)者線程進(jìn)入等待狀態(tài),直到生產(chǎn)完成后,通知消費(fèi)者線程進(jìn)行消費(fèi);
3、在消費(fèi)者線程的角度,消費(fèi)結(jié)束后,通知生產(chǎn)者線程繼續(xù)生產(chǎn),以供下一次消費(fèi);
4、在生產(chǎn)者-消費(fèi)者問(wèn)題中,光靠synchronized是不夠的:
?Synchronized可以阻止并發(fā)更新同一個(gè)共享資源,實(shí)現(xiàn)線程的同步;
?Synchronized不能用來(lái)實(shí)現(xiàn)不同線程之間的通訊;
5、我們可以通過(guò)wait()與notify()方法實(shí)現(xiàn),線程間的通訊;(wait()方法有不同的重載方法,還有notifyAll()用于喚醒所有處于等待中的線程);
6、5中提到的方法,必須要在放在同步代碼塊或是同步方法中否則會(huì)報(bào)異常;
(他們都是java.lang.Object類(lèi)的方法)
隨便說(shuō)說(shuō):
終于寫(xiě)完了,多線程之前學(xué)習(xí)的時(shí)候沒(méi)怎么學(xué)好;
這一次返回來(lái)做這一系列的文章,有感覺(jué)學(xué)到很多以前沒(méi)注意的點(diǎn);
最近在學(xué)Spring框架,卡在利用IOC容器管理Bean對(duì)象那了,總是報(bào)
java.lang.NoClassDefFoundError: org/springframework/context/ApplicationContext這樣的異常;
試了好多方法,也找了好久就是不行;
也好這兩天靜靜,復(fù)習(xí)一下學(xué)過(guò)的知識(shí);
學(xué)了三個(gè)多月的編程了,還是有種云里霧里的感覺(jué);
都說(shuō)學(xué)好框架,工作就穩(wěn)了,我這剛開(kāi)始學(xué)框架就卡住動(dòng)不了,也是有點(diǎn)醉了;也不知道以后能找到什么樣的工作;有點(diǎn)期待,又有點(diǎn)緊張;
今天是新年的第二天了,現(xiàn)在許新年愿望應(yīng)該不晚吧!
希望在新的一年了,自己能提高效率,找到工作,日語(yǔ)能力再次提升;以及祝自己身體健康,平平安安;
最后,也祝愿看到這篇文章的你,一切都往好的方面發(fā)展,平平安安,身體健康;
就說(shuō)到這吧!
感謝您的觀看!
總結(jié)
以上是生活随笔為你收集整理的多线程终极模式:生产者-消费者模式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 锁用不好,可能把自己锁住哦!(解决多线程
- 下一篇: 小小聊天室,慢慢的回忆啊!(TCP 通信