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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java生产者消费者问题代码分析

發布時間:2023/12/10 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java生产者消费者问题代码分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

作者要的是一個生產者生成,接著必須有一個消費者消費,那這不是需要單線程嗎?或者使用1個大小的阻塞隊列。所以只談論問題本身,不談論好不好。

?

具體代碼:

Java代碼 ?
  • import?java.util.concurrent.locks.Condition; ??
  • ??
  • import?java.util.concurrent.locks.Lock; ??
  • ??
  • import?java.util.concurrent.locks.ReentrantLock; ??
  • ??
  • ??
  • //生產/消費者模式 ??
  • ??
  • public?class?Basket?{ ??
  • ??
  • ????Lock?lock?=?new?ReentrantLock(); ??
  • ??
  • ??
  • ????//?產生Condition對象 ??
  • ??
  • ????Condition?produced?=?lock.newCondition(); ??
  • ??
  • ????Condition?consumed?=?lock.newCondition(); ??
  • ??
  • ????boolean?available?=?false; ??
  • ??
  • ??
  • ????public?void?produce()?throws?InterruptedException?{ ??
  • ??
  • ????????lock.lock(); ??
  • ??
  • ??
  • ????????try?{ ??
  • ??
  • ????????????if?(available)?{ ??
  • ??
  • ????????????????produced.await();?//?放棄lock進入睡眠 ??
  • ??
  • ????????????} ??
  • ??
  • ??
  • ????????????System.out.println("Apple?produced."); ??
  • ??
  • ??
  • ????????????available?=?true; ??
  • ??
  • ??
  • ????????????consumed.signal();?//?發信號喚醒等待這個Condition的線程 ??
  • ??
  • ????????}?finally?{ ??
  • ??
  • ????????????lock.unlock(); ??
  • ??
  • ????????} ??
  • ??
  • ????} ??
  • ??
  • ??
  • ????public?void?consume()?throws?InterruptedException?{ ??
  • ??
  • ????????lock.lock(); ??
  • ??
  • ??
  • ????????try?{ ??
  • ??
  • ????????????if?(!available)?{ ??
  • ??
  • ????????????????consumed.await();?//?放棄lock進入睡眠 ??
  • ??
  • ????????????} ??
  • ??
  • ??
  • ????????????/*?吃蘋果?*/??
  • ??
  • ????????????System.out.println("Apple?consumed."); ??
  • ??
  • ??
  • ????????????available?=?false; ??
  • ??
  • ??
  • ????????????produced.signal();?//?發信號喚醒等待這個Condition的線程 ??
  • ??
  • ????????}?finally?{ ??
  • ??
  • ????????????lock.unlock(); ??
  • ??
  • ????????} ??
  • ??
  • ????} ??
  • ??
  • }??
  • import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;//生產/消費者模式public class Basket {Lock lock = new ReentrantLock();// 產生Condition對象Condition produced = lock.newCondition();Condition consumed = lock.newCondition();boolean available = false;public void produce() throws InterruptedException {lock.lock();try {if (available) {produced.await(); // 放棄lock進入睡眠}System.out.println("Apple produced.");available = true;consumed.signal(); // 發信號喚醒等待這個Condition的線程} finally {lock.unlock();}}public void consume() throws InterruptedException {lock.lock();try {if (!available) {consumed.await(); // 放棄lock進入睡眠}/* 吃蘋果 */System.out.println("Apple consumed.");available = false;produced.signal(); // 發信號喚醒等待這個Condition的線程} finally {lock.unlock();}}}

    ?

    Java代碼 ?
  • import?java.util.concurrent.ExecutorService; ??
  • import?java.util.concurrent.Executors; ??
  • ??
  • //測試用類 ??
  • public?class?ConditionTester?{ ??
  • ??
  • ????public?static?void?main(String[]?args)?throws?InterruptedException?{ ??
  • ????????final?Basket?basket?=?new?Basket(); ??
  • ??
  • ????????//?定義一個producer ??
  • ????????Runnable?producer?=?new?Runnable()?{ ??
  • ????????????public?void?run()?{ ??
  • ????????????????try?{ ??
  • ????????????????????basket.produce(); ??
  • ????????????????}?catch?(InterruptedException?ex)?{ ??
  • ????????????????????ex.printStackTrace(); ??
  • ????????????????} ??
  • ????????????} ??
  • ????????}; ??
  • ??
  • ????????//?定義一個consumer ??
  • ????????Runnable?consumer?=?new?Runnable()?{ ??
  • ????????????public?void?run()?{ ??
  • ????????????????try?{ ??
  • ????????????????????basket.consume(); ??
  • ????????????????}?catch?(InterruptedException?ex)?{ ??
  • ????????????????????ex.printStackTrace(); ??
  • ????????????????} ??
  • ????????????} ??
  • ????????}; ??
  • ??
  • ????????//?各產生10個consumer和producer ??
  • ????????ExecutorService?service?=?Executors.newCachedThreadPool(); ??
  • ??
  • ????????for?(int?i?=?0;?i?<?4;?i++) ??
  • ????????????service.submit(consumer); ??
  • ??
  • ????????Thread.sleep(2000?*?2); ??
  • ??
  • ????????for?(int?i?=?0;?i?<?4;?i++) ??
  • ????????????service.submit(producer); ??
  • ??
  • ????????service.shutdown(); ??
  • ????} ??
  • }??
  • import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;//測試用類 public class ConditionTester {public static void main(String[] args) throws InterruptedException {final Basket basket = new Basket();// 定義一個producerRunnable producer = new Runnable() {public void run() {try {basket.produce();} catch (InterruptedException ex) {ex.printStackTrace();}}};// 定義一個consumerRunnable consumer = new Runnable() {public void run() {try {basket.consume();} catch (InterruptedException ex) {ex.printStackTrace();}}};// 各產生10個consumer和producerExecutorService service = Executors.newCachedThreadPool();for (int i = 0; i < 4; i++)service.submit(consumer);Thread.sleep(2000 * 2);for (int i = 0; i < 4; i++)service.submit(producer);service.shutdown();} }

    ?

    原因分析:

    1、假設前面有2個producer(此時available=true)

    1.1、一個在等待lock

    1.2、一個await

    2、consumer生成內容后,available=false,produced.signal(); 最后lock.unlock();

    3.1、因為lock.unlock所以會觸發一個lock獲取到鎖(雖然signal也會觸發等待這個條件的其他線程,但是多線程大家都知道什么時候觸發這是不確定的),如果此時正好是[1.1]那么因為available=false,執行完釋放鎖

    3.2、produced.signal()所以會觸發一個await的producer;

    ?

    解決方案:

    只要保證[3.1]還是需要await即可解決問題

    ?

    所以加一個 AtomicInteger producedAwaitCounter = new AtomicInteger(0); 統計當前等待的生產者,如果當前available=false,但已經有生產者生成了內容,那么先等待消費者消費了再說

    ?

    ? ? ? ? ? ? if (available || producedAwaitCounter.get() > 0) {

    ? ? ? ? ? ? ? ? producedAwaitCounter.incrementAndGet();

    ? ? ? ? ? ? ? ? produced.await(); // 放棄lock進入睡眠

    ? ? ? ? ? ? ? ? producedAwaitCounter.decrementAndGet();

    ? ? ? ? ? ? }

    ?

    當然最簡單的是使用:自旋,原理可以自己分析下:

    ? ? ? ? ? ? while (available) {

    ? ? ? ? ? ? ? ? produced.await(); // 放棄lock進入睡眠

    ? ? ? ? ? ? }

    ?

    ?

    Java代碼 ?
  • package?com.sishuok.es.test; ??
  • ??
  • import?java.util.concurrent.atomic.AtomicInteger; ??
  • import?java.util.concurrent.locks.Condition; ??
  • ??
  • import?java.util.concurrent.locks.Lock; ??
  • ??
  • import?java.util.concurrent.locks.ReentrantLock; ??
  • ??
  • ??
  • //生產/消費者模式 ??
  • ??
  • public?class?Basket?{ ??
  • ??
  • ????Lock?lock?=?new?ReentrantLock(true); ??
  • ??
  • ??
  • //?產生Condition對象 ??
  • ??
  • ????Condition?produced?=?lock.newCondition(); ??
  • ??
  • ????Condition?consumed?=?lock.newCondition(); ??
  • ??
  • ????boolean?available?=?false; ??
  • ????AtomicInteger?producedAwaitCounter?=?new?AtomicInteger(0); ??
  • ??
  • ??
  • ????public?void?produce()?throws?InterruptedException?{ ??
  • ??
  • ????????lock.lock(); ??
  • ??
  • ????????try?{ ??
  • ??
  • ????????????if?(available?||?producedAwaitCounter.get()?>?0)?{ ??
  • ????????????????producedAwaitCounter.incrementAndGet(); ??
  • ????????????????produced.await();?//?放棄lock進入睡眠 ??
  • ????????????????producedAwaitCounter.decrementAndGet(); ??
  • ????????????} ??
  • ??
  • ????????????System.out.println("Apple?produced."); ??
  • ??
  • ??
  • ????????????available?=?true; ??
  • ??
  • ??
  • ????????????consumed.signal();?//?發信號喚醒等待這個Condition的線程 ??
  • ??
  • ????????}?finally?{ ??
  • ????????????lock.unlock(); ??
  • ????????} ??
  • ??
  • ????} ??
  • ??
  • ??
  • ????public?void?consume()?throws?InterruptedException?{ ??
  • ??
  • ????????lock.lock(); ??
  • ??
  • ??
  • ????????try?{ ??
  • ??
  • ????????????if?(!available)?{ ??
  • ????????????????consumed.await();?//?放棄lock進入睡眠 ??
  • ????????????} ??
  • ??
  • ????????????/*?吃蘋果?*/??
  • ??
  • ????????????System.out.println("Apple?consumed."); ??
  • ??
  • ??
  • ????????????available?=?false; ??
  • ??
  • ????????????produced.signal();?//?發信號喚醒等待這個Condition的線程 ??
  • ????????}?finally?{ ??
  • ????????????lock.unlock(); ??
  • ????????} ??
  • ??
  • ????} ??
  • ??
  • }??
  • package com.sishuok.es.test;import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;//生產/消費者模式public class Basket {Lock lock = new ReentrantLock(true);// 產生Condition對象Condition produced = lock.newCondition();Condition consumed = lock.newCondition();boolean available = false;AtomicInteger producedAwaitCounter = new AtomicInteger(0);public void produce() throws InterruptedException {lock.lock();try {if (available || producedAwaitCounter.get() > 0) {producedAwaitCounter.incrementAndGet();produced.await(); // 放棄lock進入睡眠producedAwaitCounter.decrementAndGet();}System.out.println("Apple produced.");available = true;consumed.signal(); // 發信號喚醒等待這個Condition的線程} finally {lock.unlock();}}public void consume() throws InterruptedException {lock.lock();try {if (!available) {consumed.await(); // 放棄lock進入睡眠}/* 吃蘋果 */System.out.println("Apple consumed.");available = false;produced.signal(); // 發信號喚醒等待這個Condition的線程} finally {lock.unlock();}}}

    ?

    總結

    以上是生活随笔為你收集整理的java生产者消费者问题代码分析的全部內容,希望文章能夠幫你解決所遇到的問題。

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