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

溫馨提示×

溫馨提示×

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

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

Java使用阻塞隊列控制線程通信的方法實例詳解

發布時間:2020-10-19 04:28:18 來源:腳本之家 閱讀:168 作者:cakincqm 欄目:編程語言

本文實例講述了Java使用阻塞隊列控制線程通信的方法。分享給大家供大家參考,具體如下:

一 點睛

阻塞隊列主要用在生產者/消費者的場景,下面這幅圖展示了一個線程生產、一個線程消費的場景:

Java使用阻塞隊列控制線程通信的方法實例詳解

負責生產的線程不斷的制造新對象并插入到阻塞隊列中,直到達到這個隊列的上限值。隊列達到上限值之后生產線程將會被阻塞,直到消費的線程對這個隊列進行消費。同理,負責消費的線程不斷的從隊列中消費對象,直到這個隊列為空,當隊列為空時,消費線程將會被阻塞,除非隊列中有新的對象被插入。

BlockingQueue的核心方法:

方法\行為

拋異常 

特定的值

阻塞

超時

插入方法

add(o)

offer(o) 

put(o) 

offer(o, timeout, timeunit)

移除方法

 

poll(),remove(o)

take()

 poll(timeout, timeunit)

獲取、不刪除元素

element()

peek()     

 

 

行為解釋:

1.拋異常:如果操作不能馬上進行,則拋出異常。

2. 特定的值:如果操作不能馬上進行,將會返回一個特殊的值,一般是true或者false。

3. 阻塞:如果操作不能馬上進行,操作會被阻塞。

4. 超時:如果操作不能馬上進行,操作會被阻塞指定的時間,如果指定時間沒執行,則返回一個特殊值,一般是true或者false。

插入方法:

  • add(E e) : 添加成功返回true,失敗拋IllegalStateException異常。
  • offer(E e) : 成功返回 true,如果此隊列已滿,則返回 false。
  • put(E e) :將元素插入此隊列的尾部,如果該隊列已滿,則一直阻塞。

刪除方法:

  • remove(Object o) :移除指定元素,成功返回true,失敗返回false。
  • poll() : 獲取并移除此隊列的頭元素,若隊列為空,則返回 null。
  • take():獲取并移除此隊列頭元素,若沒有元素則一直阻塞。

獲取、不刪除元素:

  • element() :獲取但不移除此隊列的頭元素,沒有元素則拋異常。
  • peek() :獲取但不移除此隊列的頭;若隊列為空,則返回 null。

二 實戰1

1 代碼

import java.util.concurrent.*;
public class BlockingQueueTest
{
   public static void main(String[] args)
      throws Exception
   {
      // 定義一個長度為2的阻塞隊列
      BlockingQueue<String> bq = new ArrayBlockingQueue<>(2);
      bq.put("Java"); // 與bq.add("Java"、bq.offer("Java")相同
      bq.put("Java"); // 與bq.add("Java"、bq.offer("Java")相同
      System.out.println("打印1");
      bq.put("Java"); // ① 阻塞線程。
      System.out.println("打印2");
   }
}

2 運行

打印1

三 實戰2

1 代碼

import java.util.concurrent.*;
public class BlockingQueueTest
{
   public static void main(String[] args)
      throws Exception
   {
      // 定義一個長度為2的阻塞隊列
      BlockingQueue<String> bq = new ArrayBlockingQueue<>(2);
      bq.put("Java"); // 與bq.add("Java"、bq.offer("Java")相同
      bq.put("Java"); // 與bq.add("Java"、bq.offer("Java")相同
      System.out.println("打印1");
      //bq.put("Java"); // ① 阻塞線程。
      System.out.println("打印2");
   }
}

2 運行

打印1
打印2

四 實戰3

1 代碼

import java.util.concurrent.*;
class Producer extends Thread
{
   private BlockingQueue<String> bq;
   public Producer(BlockingQueue<String> bq)
   {
      this.bq = bq;
   }
   public void run()
   {
      String[] strArr = new String[]
      {
        "Java",
        "Struts",
        "Spring"
      };
      for (int i = 0 ; i < 5 ; i++ )
      {
        System.out.println(getName() + "生產者準備生產集合元素!");
        try
        {
           Thread.sleep(200);
           // 嘗試放入元素,如果隊列已滿,線程被阻塞
           bq.put(strArr[i % 3]);
        }
        catch (Exception ex){ex.printStackTrace();}
        System.out.println(getName() + "生產完成:" + bq);
      }
   }
}
class Consumer extends Thread
{
   private BlockingQueue<String> bq;
   public Consumer(BlockingQueue<String> bq)
   {
      this.bq = bq;
   }
   public void run()
   {
      while(true)
      {
        System.out.println(getName() + "消費者準備消費集合元素!");
        try
        {
           Thread.sleep(200);
           // 嘗試取出元素,如果隊列已空,線程被阻塞
           bq.take();
        }
        catch (Exception ex){ex.printStackTrace();}
        System.out.println(getName() + "消費完成:" + bq);
      }
   }
}
public class BlockingQueueTest2
{
   public static void main(String[] args)
   {
      // 創建一個容量為1的BlockingQueue
      BlockingQueue<String> bq = new ArrayBlockingQueue<>(1);
      // 啟動3條生產者線程
      new Producer(bq).start();
      new Producer(bq).start();
      new Producer(bq).start();
      // 啟動一條消費者線程
      new Consumer(bq).start();
   }
}

2 運行

Thread-1生產者準備生產集合元素!
Thread-2生產者準備生產集合元素!
Thread-0生產者準備生產集合元素!
Thread-3消費者準備消費集合元素!
Thread-0生產完成:[Java]
Thread-0生產者準備生產集合元素!
Thread-3消費完成:[]
Thread-2生產完成:[Java]
Thread-2生產者準備生產集合元素!
Thread-3消費者準備消費集合元素!
Thread-3消費完成:[Struts]
Thread-3消費者準備消費集合元素!
Thread-2生產完成:[Struts]
Thread-2生產者準備生產集合元素!
Thread-3消費完成:[]
Thread-0生產完成:[Struts]
Thread-3消費者準備消費集合元素!
Thread-0生產者準備生產集合元素!
Thread-3消費完成:[Java]
Thread-3消費者準備消費集合元素!
Thread-1生產完成:[Java]
Thread-1生產者準備生產集合元素!
Thread-3消費完成:[]
Thread-2生產完成:[Spring]
Thread-2生產者準備生產集合元素!
Thread-3消費者準備消費集合元素!
Thread-3消費完成:[Java]
Thread-3消費者準備消費集合元素!
Thread-2生產完成:[Java]
Thread-2生產者準備生產集合元素!
Thread-3消費完成:[]
Thread-1生產完成:[Struts]
Thread-3消費者準備消費集合元素!
Thread-1生產者準備生產集合元素!
Thread-3消費完成:[Spring]
Thread-3消費者準備消費集合元素!
Thread-1生產完成:[Spring]
Thread-1生產者準備生產集合元素!
Thread-3消費完成:[]
Thread-3消費者準備消費集合元素!
Thread-2生產完成:[Struts]
Thread-3消費完成:[]
Thread-0生產完成:[Spring]
Thread-0生產者準備生產集合元素!
Thread-3消費者準備消費集合元素!
Thread-1生產完成:[Java]
Thread-1生產者準備生產集合元素!
Thread-3消費完成:[Java]
Thread-3消費者準備消費集合元素!
Thread-3消費完成:[]
Thread-0生產完成:[Java]
Thread-0生產者準備生產集合元素!
Thread-3消費者準備消費集合元素!
Thread-3消費完成:[]
Thread-3消費者準備消費集合元素!
Thread-0生產完成:[Struts]
Thread-3消費完成:[]
Thread-3消費者準備消費集合元素!
Thread-1生產完成:[Struts]
Thread-3消費完成:[]
Thread-3消費者準備消費集合元素!

更多java相關內容感興趣的讀者可查看本站專題:《Java進程與線程操作技巧總結》、《Java數據結構與算法教程》、《Java操作DOM節點技巧總結》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總》

希望本文所述對大家java程序設計有所幫助。

向AI問一下細節

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

AI

利津县| 林甸县| 福建省| 永济市| 宿州市| 洪洞县| 温泉县| 镇雄县| 玉环县| 石楼县| 建始县| 巴林左旗| 洛川县| 四会市| 定陶县| 梨树县| 汉中市| 集贤县| 云安县| 洛川县| 元江| 法库县| 胶州市| 崇州市| 军事| 邵东县| 进贤县| 德安县| 信宜市| 金昌市| 永登县| 和田市| 洪洞县| 从江县| 建昌县| 嵩明县| 太康县| 合川市| 卓尼县| 满城县| 成安县|