最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java中生產(chǎn)者消費(fèi)者問題和代碼案例

 更新時間:2022年02月08日 11:14:18   作者:yuuunfryan  
大家好,本篇文章主要講的是java中生產(chǎn)者消費(fèi)者問題和代碼案例,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下

應(yīng)用場景

假設(shè)倉庫中只能存放一件產(chǎn)品,生產(chǎn)者將生產(chǎn)出來的產(chǎn)品放入倉庫,消費(fèi)者將倉庫中產(chǎn)品取走消費(fèi)

如果倉庫中沒有產(chǎn)品,則生產(chǎn)者將產(chǎn)品放入倉庫,否則停止生產(chǎn)并等待,直到倉庫中的產(chǎn)品被消費(fèi)者取走為止

如果倉庫中放有產(chǎn)品,則消費(fèi)者可以將產(chǎn)品取走消費(fèi),否則停止消費(fèi)并等待,直到倉庫中再次放入產(chǎn)品為止

分析

這是一個線程同步問題,生產(chǎn)者和消費(fèi)者共享同一個資源,并且生產(chǎn)者和消費(fèi)者之間相互依賴,互為條件。

對于生產(chǎn)者,沒有生產(chǎn)產(chǎn)品之前,要通知消費(fèi)者等待,而生產(chǎn)了產(chǎn)品之后,又需要馬上通知消費(fèi)者消費(fèi)

對于消費(fèi)者,在消費(fèi)之后,要通知生產(chǎn)者已經(jīng)結(jié)束消費(fèi),需要生產(chǎn)新的產(chǎn)品以供消費(fèi)

在生產(chǎn)者消費(fèi)者問題中,僅有synchronized是不夠的

synchronized可阻止并發(fā)更新同一個共享資源,實(shí)現(xiàn)了同步

synchronized不能用來實(shí)現(xiàn)不同線程之間的消息傳遞(通信)

Java提供了幾個方法解決線程之間的通信問題

方法名作用
wait()表示線程一直等待,直到其他線程通知,與sleep不同,wait()會釋放鎖
wait(long timeout)指定等待的毫秒數(shù)
notify()喚醒一個處于等待狀態(tài)的線程
notifyAll()喚醒同一個對象上所有調(diào)用wait()方法的線程,優(yōu)先級別高的線程優(yōu)先調(diào)度

注意:均是Object類的方法,都只能在同步方法或者同步代碼塊中使用,否則會拋出異常

解決方法

管程法

生產(chǎn)者:負(fù)責(zé)生產(chǎn)數(shù)據(jù)的模塊(可能是方法、對象、線程、進(jìn)程)

消費(fèi)者:負(fù)責(zé)處理數(shù)據(jù)的模塊(可能是方法、對象、線程、進(jìn)程)

緩沖區(qū):消費(fèi)者不能直接使用生產(chǎn)者的數(shù)據(jù),他們之間有個“緩沖區(qū)”

生產(chǎn)者將生產(chǎn)好的數(shù)據(jù)放入緩沖區(qū),消費(fèi)者從緩沖區(qū)拿出數(shù)據(jù)

代碼案例

//使用緩沖區(qū)解決生產(chǎn)者消費(fèi)者模型
public class TestPC {
    public static void main(String[] args) {
        SynContainer container = new SynContainer();
        new Producer(container).start();
        new Consumer(container).start();
    }
}
?
class Producer extends Thread{
    SynContainer synContainer;
    public Producer(SynContainer synContainer){
        this.synContainer = synContainer;
    }
    //  生產(chǎn)
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            synContainer.push(new Chicken(i));
            System.out.println("生產(chǎn)了"+i+"只雞");
        }
    }
}
?
class Consumer extends Thread{
    SynContainer synContainer;
    public Consumer(SynContainer synContainer){
        this.synContainer = synContainer;
    }
    //  消費(fèi)
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("消費(fèi)了-->"+synContainer.pop().id+"只雞");
        }
    }
}
?
//產(chǎn)品
class Chicken{
    int id;
    public Chicken(int id) {
        this.id = id;
    }
}
?
//緩沖區(qū)
class SynContainer{
    Chicken[] chickens = new Chicken[10];
    int count = 0;
    //生產(chǎn)者放入產(chǎn)品
    public synchronized void push(Chicken chicken){
        //如果容器滿了就要等到消費(fèi)者消費(fèi)
        if (count==chickens.length){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //通知消費(fèi)者消費(fèi),自身進(jìn)入等待
        }
        //沒有滿的話則生產(chǎn)
        chickens[count] = chicken;
        count++;
        //通知消費(fèi)者消費(fèi)
        this.notifyAll();
    }
?
    //生產(chǎn)者消費(fèi)產(chǎn)品
    public synchronized Chicken pop(){
        if (count==0){
            //等待生產(chǎn)者生產(chǎn)
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        count--;
        Chicken chicken = chickens[count];
        //消費(fèi)了,可以通知生產(chǎn)者繼續(xù)生產(chǎn)
        this.notifyAll();
        return chicken;
    }
}

信號燈法

通過標(biāo)志位 true 或者 false 來進(jìn)行判斷

代碼案例

//信號燈法測試生產(chǎn)者消費(fèi)者模型 即標(biāo)志位
public class TestPC2 {
    public static void main(String[] args) {
        TV tv = new TV();
        new Player(tv).start();
        new Audiance(tv).start();
    }
?
}
?
//生產(chǎn)者-->演員
class Player extends Thread {
    TV tv;
    public Player(TV tv){
        this.tv = tv;
    }
?
    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            if (i%2==0){
                this.tv.play("天天向上");
            }else {
                this.tv.play("抖音廣告");
            }
        }
    }
}
?
//消費(fèi)者-->觀眾
class  Audiance extends Thread{
    TV tv;
    public Audiance(TV tv){
        this.tv = tv;
    }
?
    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            tv.watch();
        }
    }
}
?
//產(chǎn)品-->節(jié)目
class TV{
    //演員表演 觀眾等待 T
    //觀眾觀看 演員等待 F
    String show;//表演的節(jié)目
    boolean flag = true;
?
    //表演
    public synchronized void play(String show){
        if (!flag){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("演員表演了:"+show);
        //通知觀眾
        this.notifyAll();
        this.show = show;
        this.flag = !this.flag;
    }
?
    //觀看
    public synchronized void watch(){
        if (flag){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("觀看了"+show);
        //通知演員表演
        this.notifyAll();
        this.flag = !this.flag;
    }
}

總結(jié)

到此這篇關(guān)于java中生產(chǎn)者消費(fèi)者問題和代碼案例的文章就介紹到這了,更多相關(guān)java生產(chǎn)者消費(fèi)者問題內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring中集成Groovy的四種方式(小結(jié))

    Spring中集成Groovy的四種方式(小結(jié))

    這篇文章主要介紹了Spring中集成Groovy的四種方式,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • 使用?mybatis?自定義日期類型轉(zhuǎn)換器的示例代碼

    使用?mybatis?自定義日期類型轉(zhuǎn)換器的示例代碼

    這篇文章主要介紹了使用?mybatis?自定義日期類型轉(zhuǎn)換器的示例代碼,這里使用mybatis中的typeHandlers?實(shí)現(xiàn)的,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-03-03
  • MyBatis的mapper.xml文件中入?yún)⒑头祷刂档膶?shí)現(xiàn)

    MyBatis的mapper.xml文件中入?yún)⒑头祷刂档膶?shí)現(xiàn)

    這篇文章主要介紹了MyBatis的mapper.xml文件中入?yún)⒑头祷刂档膶?shí)現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • 詳解Java比較器

    詳解Java比較器

    這篇文章主要介紹了Java比較器的相關(guān)資料,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • java高效實(shí)現(xiàn)大文件拷貝功能

    java高效實(shí)現(xiàn)大文件拷貝功能

    這篇文章主要為大家詳細(xì)介紹了java高效實(shí)現(xiàn)大文件拷貝功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-05-05
  • Java應(yīng)用打包后運(yùn)行需要注意編碼問題

    Java應(yīng)用打包后運(yùn)行需要注意編碼問題

    這篇文章主要介紹了 Java應(yīng)用打包后運(yùn)行需要注意編碼問題的相關(guān)資料,需要的朋友可以參考下
    2016-12-12
  • Java ArrayList類的基礎(chǔ)使用講解

    Java ArrayList類的基礎(chǔ)使用講解

    數(shù)組的長度是固定的,無法適應(yīng)數(shù)據(jù)變化的需求。為了解決這個問題,Java提供了另一個容器 java.util.ArrayList集合類,讓我們可以更便捷的存儲和操作對象數(shù)據(jù)。本文就將通過示例聊聊ArrayList類的基礎(chǔ)使用,感興趣的可以了解一下
    2022-10-10
  • SpringBoot如何配置Controller實(shí)現(xiàn)Web請求處理

    SpringBoot如何配置Controller實(shí)現(xiàn)Web請求處理

    這篇文章主要介紹了SpringBoot如何配置Controller實(shí)現(xiàn)Web請求處理,文中通過圖解示例介紹的很詳細(xì),具有有一定的參考價值,需要的小伙伴可以參考一下
    2023-05-05
  • 如何將二進(jìn)制文件流轉(zhuǎn)化為MockMultipartFile文件

    如何將二進(jìn)制文件流轉(zhuǎn)化為MockMultipartFile文件

    文章主要介紹了如何使用Spring框架中的MockMultipartFile類來模擬文件上傳,并處理上傳邏輯,包括獲取二進(jìn)制文件流、創(chuàng)建MockMultipartFile對象、處理上傳邏輯和返回響應(yīng),還解釋了MockMultipartFile的功能和二進(jìn)制文件流的定義
    2025-02-02
  • java實(shí)現(xiàn)會反彈的小球示例

    java實(shí)現(xiàn)會反彈的小球示例

    這篇文章主要介紹了java實(shí)現(xiàn)會反彈的小球示例,需要的朋友可以參考下
    2014-04-04

最新評論

菏泽市| 怀化市| 巩留县| 绥江县| 米易县| 普安县| 桦甸市| 铁岭县| 巴彦县| 修文县| 喀喇| 广宗县| 泉州市| 商河县| 遂平县| 东海县| 博客| 岳西县| 肥乡县| 甘孜县| 沈丘县| 弥勒县| 称多县| 广丰县| 镇安县| 武汉市| 乐亭县| 桃源县| 任丘市| 曲阜市| 吴旗县| 金沙县| 临汾市| 上虞市| 海丰县| 马公市| 许昌市| 都江堰市| 徐州市| 吉林市| 正安县|