欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java線程通信中關(guān)于生產(chǎn)者與消費(fèi)者案例分析

 更新時(shí)間:2021年09月14日 09:10:28   作者:威斯布魯克.猩猩  
這篇文章主要介紹了Java線程通信中關(guān)于生產(chǎn)者與消費(fèi)者案例,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

相關(guān)方法:
wait():一旦執(zhí)行此方法,當(dāng)前線程就進(jìn)入阻塞狀態(tài),并釋放同步監(jiān)視器。
notify():一旦執(zhí)行此方法,就會(huì)喚醒被wait的一個(gè)線程,如果有多個(gè)線程被wait,就喚醒優(yōu)先級(jí)高的那個(gè)。
notifyAll():一旦執(zhí)行此方法,就會(huì)喚醒所有被wait的線程。
說(shuō)明:
1.wait(),notify(),notifyAll()三個(gè)方法必須使用在同步代碼塊或同步方法中。
2.wait(),notify(),notifyAll()三個(gè)方法的調(diào)用者必須是同步代碼塊或同步方法中的同步監(jiān)視器。
否則,會(huì)出現(xiàn)IllegalMonitorStateException異常
3.wait(),notify(),notifyAll()三個(gè)方法是定義在java.lang.Object類中。

線程通信的例子:使用兩個(gè)線程打印1-100.線程1,線程2 交替打印

class Number implements Runnable{
    private int number = 1;
    @Override
    public void run() {
        while(true){
            synchronized (this) {
                notify();
                if(number <= 100){
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + ":" + number);
                    number++;
                    try {
                        //使得調(diào)用如下wait()方法的線程進(jìn)入阻塞狀態(tài)
                        wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }else{
                    break;
                }
            }
        }
    }
}
public class CommunicationTest {
    public static void main(String[] args) {
        Number number = new Number();
        Thread t1 = new Thread(number);
        Thread t2 = new Thread(number);
        t1.setName("線程1");
        t2.setName("線程2");
        t1.start();
        t2.start();
    }
}

經(jīng)典例題:生產(chǎn)者/消費(fèi)者問(wèn)題

生產(chǎn)者(Productor)將產(chǎn)品交給店員(Clerk),而消費(fèi)者(Customer)從店員處取走產(chǎn)品店員一次只能持有固定數(shù)量的產(chǎn)品(比如:20),如果生產(chǎn)者試圖生產(chǎn)更多的產(chǎn)品,店員會(huì)叫生產(chǎn)者停一下,如果店中有空位放產(chǎn)品了再通知生產(chǎn)者繼續(xù)生產(chǎn),如果店中沒(méi)有產(chǎn)品了,店員會(huì)告訴消費(fèi)者等一下,如果店中有產(chǎn)品了再通知消費(fèi)者來(lái)取走產(chǎn)品。

這里可能出現(xiàn)兩個(gè)問(wèn)題:

>生產(chǎn)者比消費(fèi)者快時(shí),消費(fèi)者會(huì)漏掉一些數(shù)據(jù)沒(méi)有取到。

>消費(fèi)者比生產(chǎn)者塊時(shí),消費(fèi)者會(huì)取相同的數(shù)據(jù)。

分析:

  1. 是否是多線程問(wèn)題?是,生產(chǎn)者線程,消費(fèi)者線程
  2. 是否有共享數(shù)據(jù)?有,店員(或產(chǎn)品)
  3. 如何解決線程安全問(wèn)題?同步機(jī)制,有三種方法
  4. 是否涉及線程的通信?是
class Clerk{
    private int productCount = 0;
    //生產(chǎn)產(chǎn)品
    public synchronized void produceProduct() {
        if(productCount < 20){
            productCount++;
            System.out.println(Thread.currentThread().getName() + ":開始生產(chǎn)第" + productCount + "個(gè)產(chǎn)品");
            notify();
        }else{
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    //消費(fèi)產(chǎn)品
    public synchronized void consumeProduct() {
        if(productCount > 0){
            System.out.println(Thread.currentThread().getName() + ":開始消費(fèi)第" + productCount + "個(gè)產(chǎn)品");
            productCount--;
            notify();
        }else{
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
class Producer extends Thread{//生產(chǎn)者
    private Clerk clerk;
    public Producer(Clerk clerk){
        this.clerk = clerk;
    }
    @Override
    public void run() {
        System.out.println(getName() + ":開始生產(chǎn)產(chǎn)品.....");
        while(true){
            try {
                sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            clerk.produceProduct();
        }
    }
}
class Consumer extends Thread{//消費(fèi)者
    private Clerk clerk;
    public Consumer(Clerk clerk){
        this.clerk = clerk;
    }
    @Override
    public void run() {
        System.out.println(getName() + ":開始消費(fèi)產(chǎn)品.....");
        while(true){
            try {
                sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            clerk.consumeProduct();
        }
    }
}
public class ProductTest {
    public static void main(String[] args) {
        Clerk clerk = new Clerk();
        Producer p1 = new Producer(clerk);
        p1.setName("生產(chǎn)者1");
        Consumer c1 = new Consumer(clerk);
        c1.setName("消費(fèi)者1");
        Consumer c2 = new Consumer(clerk);
        c2.setName("消費(fèi)者2");
        p1.start();
        c1.start();
        c2.start();
    }
}

sleep()和wait()的異同?

1.相同點(diǎn):一旦執(zhí)行方法,都可以使得當(dāng)前的線程進(jìn)入阻塞狀態(tài)。
2.不同點(diǎn):

1)兩個(gè)方法聲明的位置不同,Thread類中聲明sleep(),Object類中聲明wait()

2)調(diào)用的要求不同:sleep()可以在任何需要的場(chǎng)景下調(diào)用。wait()必須使用在同步代碼塊或同步方 法中

3)關(guān)于是否釋放同步監(jiān)視器:如果兩個(gè)方法都使用在同步代碼塊或同步方法中,sleep()不會(huì)釋放 鎖,wait()會(huì)釋放鎖

到此這篇關(guān)于Java線程通信中關(guān)于生產(chǎn)者與消費(fèi)者案例分析的文章就介紹到這了,更多相關(guān)Java線程通信內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • springboot后端接收前端傳數(shù)組參數(shù)三種方法

    springboot后端接收前端傳數(shù)組參數(shù)三種方法

    這篇文章主要給大家介紹了關(guān)于springboot后端接收前端傳數(shù)組參數(shù)三種方法,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2023-07-07
  • Java多線程中的CountDownLatch解析

    Java多線程中的CountDownLatch解析

    這篇文章主要介紹了Java多線程中的CountDownLatch解析,CountDownLatch是一個(gè)阻塞部分線程直到其他線程執(zhí)行完成后喚醒的同步計(jì)數(shù)器,核心是其內(nèi)部類Sync繼承于AQS,同時(shí)也是利用的AQS的同步原理,也稱之為閉鎖,需要的朋友可以參考下
    2023-11-11
  • springmvc組件中的HandlerMapping解析

    springmvc組件中的HandlerMapping解析

    這篇文章主要介紹了springmvc九大組件中的HandlerMapping解析,HandlerMapping表示的是一個(gè)URL與一個(gè)Handler(可以簡(jiǎn)單的理解為Controller中有@RequestMapping注解的方法)之間的映射關(guān)系,需要的朋友可以參考下
    2023-09-09
  • Java讀取項(xiàng)目json文件并轉(zhuǎn)為JSON對(duì)象的操作

    Java讀取項(xiàng)目json文件并轉(zhuǎn)為JSON對(duì)象的操作

    這篇文章主要介紹了Java讀取項(xiàng)目json文件并轉(zhuǎn)為JSON對(duì)象的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • MyEclipse如何取消默認(rèn)工作空間方法示例

    MyEclipse如何取消默認(rèn)工作空間方法示例

    這篇文章主要介紹了MyEclipse如何取消默認(rèn)工作空間,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • Java數(shù)據(jù)結(jié)構(gòu)與算法之棧(動(dòng)力節(jié)點(diǎn)Java學(xué)院整理)

    Java數(shù)據(jù)結(jié)構(gòu)與算法之棧(動(dòng)力節(jié)點(diǎn)Java學(xué)院整理)

    這篇文章主要介紹了Java數(shù)據(jù)結(jié)構(gòu)與算法之棧,棧是先進(jìn)后出的數(shù)據(jù)的結(jié)構(gòu),本文通過(guò)文字說(shuō)明與實(shí)例代碼相結(jié)合的形式給大家介紹的非常詳細(xì),需要的朋友跟著小編一起學(xué)習(xí)吧
    2017-04-04
  • Mybatis-Plus實(shí)現(xiàn)公共字段自動(dòng)賦值的方法

    Mybatis-Plus實(shí)現(xiàn)公共字段自動(dòng)賦值的方法

    這篇文章主要介紹了Mybatis-Plus實(shí)現(xiàn)公共字段自動(dòng)賦值的方法,涉及到通用字段自動(dòng)填充的最佳實(shí)踐總結(jié),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-07-07
  • 利用POI生成EXCEL文件的方法實(shí)例

    利用POI生成EXCEL文件的方法實(shí)例

    Apache POI 是用Java編寫的免費(fèi)開源的跨平臺(tái)的 Java API,Apache POI提供API給Java程式對(duì)Microsoft Office格式檔案讀和寫的功能,下面這篇文章主要給大家介紹了關(guān)于利用POI生成EXCEL文件的相關(guān)資料,需要的朋友可以參考下
    2018-07-07
  • springboot與mybatis整合實(shí)例詳解(完美融合)

    springboot與mybatis整合實(shí)例詳解(完美融合)

    大家都知道springboot搭建一個(gè)spring框架只需要秒秒鐘。下面通過(guò)實(shí)例代碼給大家介紹一下springboot與mybatis的完美融合,非常不錯(cuò),具有參考借鑒價(jià)值,感興趣的朋友一起看看吧
    2016-09-09
  • spring boot整合mybatis+mybatis-plus的示例代碼

    spring boot整合mybatis+mybatis-plus的示例代碼

    這篇文章主要介紹了spring boot整合mybatis+mybatis-plus的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-01-01

最新評(píng)論