日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java多线程(3)—生产者/消费者

發布時間:2025/3/20 java 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java多线程(3)—生产者/消费者 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這個是一個典型的線程問題。生成者(Productor)生產商品并交給店員(Clerk),消費者(Customer)從店員處購買商品,店員一次性只能購買固定數量的產品,如果生產者試圖生成更多的商品,店員會叫生產者暫停一下,如果店里倉庫有空位再通知生產者繼續生產,如果店中沒有商品了,就會告訴消費者等一下,如果店中有商品了就通知消費者來購買。這個場景和我們實際情況也比較貼切,這樣就會想可能存在如下問題:

  • 生產者比消費者快的時,消費者會漏掉部分數據取不到(產品過剩導致浪費,出現滯銷)
  • 消費者比生產者快時,消費者會取到相同的數據(產量不足,供不應求)
  • 在解決這個方法之前先介紹一下線程通信

    所謂線程通信可以這樣理解:線程與線程之間不是相互獨立的個體,它們彼此之間需要相互通信和協作,最典型的例子就是生產者-消費者問題:當隊列滿時,生產者需要等待隊列有空間才能繼續往里面放入商品,而在等待的期間內,生產者必須釋放對臨界資源(即隊列)的占用權。因為生產者如果不釋放對臨界資源的占用權,那么消費者就無法消費隊列中的商品,就不會讓隊列有空間,那么生產者就會一直無限等待下去。因此一般情況下,當隊列滿時,會讓生產者交出對臨界資源的占用權,并進入掛起狀態。然后等待消費者消費了商品,然后消費者通知生產者隊列有空間了。同樣地,當隊列空時,消費者也必須等待,等待生產者通知它隊列中有商品了。這種互相通信的過程就是線程間的協作。

    1.notify/wait

    前面的文中通過包括 static?synchronized 等手段來解決數據共享的問題,即多個線程主動地讀取一個共享數據,通過 同步互斥訪問機制保證線程的安全性。等待/通知機制主要由Object類中的wait()、notify() 和 notifyAll()三個方法來實現。

    wait():令當前線程掛起并放棄CPU、同步資源,讓其他線程可以訪問并修改共享資源,而當前現場排隊等候以獲得再次對資源的訪問機會

    notify():喚醒正在排隊等待同步資源的線程中優先級最高者結束等待

    notifyAll():喚醒正在排隊等待資源的所有線程結束等待。

    注意:

  • 這三個方法均非Thread類中所聲明的方法,而是Object類中聲明的方法。原因是每個對象都擁有monitor(鎖),所以讓當前線程等待某個對象的鎖,當然應該通過這個對象來操作,而不是用當前線程來操作,因為當前線程可能會等待多個線程的鎖,如果通過線程來操作,就非常復雜了。
  • Java.lang.Object提供的這三個方法只能在synchronized方法或synchronized代碼塊中使用
  • package blog;public class TestAccount {public static void main(String[] args) {Account account = new Account();Account account1 = new Account();//多線程對象User u_weixin = new User(account, 2000);User u_zhifubao = new User(account, 2000);Thread weixin = new Thread(u_weixin,"微信賬戶");Thread zhifubao = new Thread(u_zhifubao,"支付寶賬戶");weixin.start();zhifubao.start();} }class Account{public static int money = 3000;public void takeMoney5(int m,Account a) {synchronized(a){//表示當前對象的代碼被加入了synchronized同步鎖,this表示當前對象String name = Thread.currentThread().getName();//如果是微信操作則等待,等支付寶操作完成再給微信操作if (name.equals("微信賬戶")) {try {a.wait();//當前線程等待進入阻塞狀態} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if (m > money) {System.out.println(name + "操作,賬戶金額不足:"+money);}else {System.out.println(name + "操作,賬戶原有金額:"+money);System.out.println(name + "操作,取款金額:" + m);money = money - m;System.out.println(name + "操作,取款后的余額:" + money);}if (name.equals("支付寶賬戶")) {try {a.notify();//喚醒當前優先級最高的線程,進入就緒狀態} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}}class User implements Runnable{Account account;int money;public User(Account account,int money) {this.account = account;this.money = money;}@Overridepublic void run() {account.takeMoney5(money,account);} }

    輸出結果如下:

    2.生產者/消費者

    結合上述介紹的notify/wait機制,下面來實現生產者和消費者

    package day15;public class Test3 {public static void main(String[] args) {Clerk c = new Clerk();//消費時不生產,生產時不消費//生產者new Thread(new Runnable() {@Overridepublic void run() {synchronized (c) {while (true) {//無限循環表示無限生產if (c.productNum == 0) {System.out.println("商品數為0,開始生產");while (c.productNum < 5) {c.productNum++;//生產之后,增加商品System.out.println("庫存值:"+c.productNum);}System.out.println("產品數為:" + c.productNum +"結束生產");c.notify();//喚醒消費者,讓生產者線程等待}else {try {c.wait();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}}},"生產者").start();//消費時不生產,生產時不消費//生產者new Thread(new Runnable() {@Overridepublic void run() {synchronized (c) {while (true) {//無限循環表示無限消費if (c.productNum == 5) {System.out.println("商品數為4,開始消費");while (c.productNum > 0) {c.productNum--;//消費產品,產品減少System.out.println("庫存值:"+c.productNum);}System.out.println("產品數為:" + c.productNum +"結束消費");c.notify();//喚醒生產者,讓消費者線程等待}else {try {c.wait();//消費者線程等待} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}}},"消費者").start();} }class Clerk{public static int productNum = 0;}

    輸出結果如下:

    ?

    ?

    ?

    ?

    ?

    ?

    總結

    以上是生活随笔為你收集整理的Java多线程(3)—生产者/消费者的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。