中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java多線程中消費者與生產者的關系是什么

發布時間:2021-11-20 14:21:33 來源:億速云 閱讀:147 作者:小新 欄目:編程語言

這篇文章將為大家詳細講解有關Java多線程中消費者與生產者的關系是什么,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

  多線程:CPU中各種任務在交替執行過程中,被稱為多線程處理。其中,每個任務的一次動態執行過程被稱為進程。進程執行過程中的暫停被稱為中斷。進程通過中斷被分解成若干段,每一段被稱為一個線程。

  在消費者與生產者中,我們設定單個生產者的每次活動是饅頭 +1;單個消費者每次進行的是饅頭 -1;然后消費者和生產者的活動時間不確定,同時生產者和消費者的數量不確定,該經典問題我們使用多線程實現:

  我們首先確定實物,即生產者的每次生成的物品,在這里我們使用饅頭代替。在WoTou的類中,我們可以看到有著自己獨特的屬性,即饅頭的 id,我們可以在控制臺清晰的看到饅頭的生產和消費過程,具體實現代碼如下:

  class WoTou{ //饅頭,生產者生產的饅頭

  int id;

  WoTou(int id){

  this.id = id;

  }

  public String toString(){

  return "WoTou:"+ id;

  }

  }

  我們需要確定饅頭的存儲容器,即在消費和生產發生的時候,我們需要在什么地方進行判斷,饅頭是否耗盡,或者饅頭是否滿溢。每次活動都是相當于在棧中取東西和放東西,所以我們根據棧的特性為:先進后出 原則。

  class SyncStack {//籃子容器,放饅頭用的

  int index = 0;

  WoTou[] arrWT = new WoTou[6];

  }

  在籃子容器中我們簡單定義棧的最大容量為6,我們之后設定生產者的類,定義為producer類。我們知道producer有著一些自己的獨特屬性,即往籃子SyncStack中放WoTou,每次進行饅頭+1操作,還有生產者的操作Time間隔,是隔10毫秒還是5毫秒,我們使得producer類實現其Runnerable接口,調用線程的run()方法,具體代碼如下:

  class Producer implements Runnable{ //生產者

  SyncStack ss= null;

  Producer(SyncStack ss){

  this.ss = ss;

  }

  public void run(){

  for(int i=0;i<20;i++){

  WoTou wt = new WoTou(i);

  ss.push(wt);

  System.out.println("生產者:"+wt);

  try {

  Thread.sleep((int)(Math.random()*1000));

  } catch (InterruptedException e) {

  // TODO: handle exception

  e.printStackTrace();

  }

  }

  }

  }

  生產者在往棧中添加數據的時候,我們使用push方法進行插入。同時定義插入的饅頭數量,這里的數量并不是籃子的饅頭數量。籃子里邊雖然只能一次性裝6個饅頭,但是消費者是同時間進行操作的,所以籃子的饅頭數量在消費之后,生產者繼續進行生產,一直到生產20個饅頭為止。

  消費者我們這里定義為Consumer類,消費者和生產者有一定的相似性,但是我們需要消費在籃子中拿的過程,我們使用pop操作,同時定義消費數量,以及操作間隔,這里都是使用線程的sleep(時間)方法, 代碼如下:

  class Consumer implements Runnable{ //消費者

  SyncStack ss= null;

  Consumer(SyncStack ss){

  this.ss = ss;

  }

  public void run(){

  for(int i=0;i<20;i++){

  WoTou wt = ss.pop();

  System.out.println("消費量:"+wt);

  try {

  Thread.sleep((int)(Math.random()*1000));

  } catch (InterruptedException e) {

  // TODO: handle exception

  e.printStackTrace();

  }

  }

  }

  }

  最后我們考慮在籃子中,假如容量已滿,即生產者生產過多,消費的太慢,那么生產者需要休息;同樣的消費過快,容器數量為0,消費者開始休息。我們在兩種情況發生的時候,需要設置兩種方法,在極限情況發生的時候,進行判斷。簡單實現代碼如下:

  public synchronized void push(WoTou wt){ //往籃子中放饅頭

  while(index == arrWT.length){

  try {

  this.wait();

  } catch (InterruptedException e) {

  // TODO: handle exception

  e.printStackTrace();

  }

  }

  this.notify();

  arrWT[index] = wt;

  index++;

  }鄭州人流多少錢 http://mobile.sgyy029.com/

  我們需要確定是我們在生產者進行活動的時候,不能受到其他線程的影響,即我們需要保持在某一時刻只有一個線程進行操作,這種情況我們需要使用線程的一個synchronized方法。這個方法稱為死鎖,鎖定當前方法體執行的過程中,保持其獨立性。即在方法體的前面使用synchronized關鍵字修飾。

  從籃子中取出饅頭的操作類似于生產者,實現代碼如下:

  public synchronized WoTou pop(){ //從籃子中取饅頭

  while(index == 0){

  try {

  this.wait();

  } catch (InterruptedException e) {

  // TODO: handle exception

  e.printStackTrace();

  }

  }

  this.notify();

  index--;

  return arrWT[index];

  }

  我們會發現在上面兩種動作中,考慮到一個問題,即數量到極限之后,我們的動作停止了。生產者在籃子容量到達6時,動作停止;消費者在籃子數量到0后,停止行為。我們這時候開始使用線程的notify方法,喚醒休眠的線程,因為線程使用了wait方法,我們可以喚醒之后,在進行各自的行為。因此籃子SynStack類中詳細代碼為:

  class SyncStack {//籃子容器,放饅頭用的

  int index = 0;

  WoTou[] arrWT = new WoTou[6];

  public synchronized void push(WoTou wt){ //往籃子中放饅頭

  while(index == arrWT.length){

  try {

  this.wait(); //線程等待

  } catch (InterruptedException e) {

  // TODO: handle exception

  e.printStackTrace();

  }

  }

  this.notify(); //喚醒wait的線程

  arrWT[index] = wt;

  index++;

  }

  public synchronized WoTou pop(){ //從籃子中取饅頭

  while(index == 0){

  try {

  this.wait();

  } catch (InterruptedException e) {

  // TODO: handle exception

  e.printStackTrace();

  }

  }

  this.notify();

  index--;

  return arrWT[index];

  }

  }

  我們可以修改生產者和消費者的數量和操作間隔,不一定生產+1同時消費-1。我們可以根據修改進行更改代碼,上面的運行在控制臺數據

關于“Java多線程中消費者與生產者的關系是什么”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

辽源市| 醴陵市| 武平县| 视频| 惠水县| 邯郸县| 辽宁省| 新龙县| 那曲县| 连平县| 呼伦贝尔市| 新河县| 田东县| 乌兰察布市| 图木舒克市| 东源县| 罗平县| 通州区| 广丰县| 林芝县| 和林格尔县| 绵竹市| 同德县| 龙井市| 陆良县| 丹寨县| 平武县| 湛江市| 烟台市| 揭西县| 若尔盖县| 琼海市| 十堰市| 邯郸市| 疏附县| 仙桃市| 津南区| 高要市| 阜新市| 南澳县| 永登县|