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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java并发编程之阻塞队列

發布時間:2024/2/28 java 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java并发编程之阻塞队列 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Java并發編程之阻塞隊列


目錄

  • 阻塞隊列概述
  • 為什么用?有什么好處?
  • BlockingQueue的核心方法
  • SynchronousQueue的用法
  • 用在哪里

  • 1. 阻塞隊列概述


  • 阻塞隊列,顧名思義,首先它是一個隊列,而一個阻塞隊列在數據結構中起到的作業大致如下圖所示:
  • 當線程隊列是空時,從隊列中獲取元素的操作將會被阻塞。
  • 試圖從空的阻塞隊列中獲取元素的線程將會被阻塞,直到其他的線程往空的隊列插入新的元素。
  • 同樣,試圖往已滿的阻塞隊列中添加新元素的線程也同樣會被阻塞,直到其他的線程從列總移除一個或多個元素或者完全清空隊列后使隊列重新變得空閑起來并后續新增。

  • 2. 為什么用?有什么好處?


  • 在多線程領域;所謂阻塞,在某些情況下會掛起線程(即阻塞),一旦條件滿足,被掛起的線程又會自動被喚醒
  • 為什么需要BlockingQueue?
    • 好處是我們不需要關心什么時候需要阻塞線程,什么時候需要喚醒線程,因為這一切BlockingQueue都給你一手包辦了
  • 在concurrent包發布以前,在多線程環境下,我們每個程序員都必須去自己控制這些細節,尤其還要兼顧效率和線程安全,而
    這會給我們的程序帶來不小的復雜度。

  • 3. BlockingQueue的核心方法


    1. 核心方法概述



    2. 核心方法api使用


    1. 阻塞隊列api之拋出異常組

    代碼:

    public class BlockingQueueDemo {public static void main(String[] args) {BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);System.out.println("添加元素" + blockingQueue.add("a"));System.out.println("添加元素" + blockingQueue.add("b"));System.out.println("添加元素" + blockingQueue.add("c")); // System.out.println("添加元素" + blockingQueue.add("d"));//檢查隊列第一個元素System.out.println(blockingQueue.element());System.out.println("移除元素" + blockingQueue.remove());System.out.println("移除元素" + blockingQueue.remove());System.out.println("移除元素" + blockingQueue.remove()); // System.out.println("移除元素"+blockingQueue.remove());} }

    1.1 正常執行結果:


    1.2 將注釋的代碼System.out.println("添加元素" + blockingQueue.add("d"));打開。即:

    執行結果:

    報異常:java.lang.IllegalStateException: Queue full


    1.3 將注釋的代碼System.out.println("移除元素" + blockingQueue.remove());打開,即:

    執行結果:

    報異常:Exception in thread “main” java.util.NoSuchElementException


    1.4 小結:

  • 當阻塞隊列滿時,再往隊列里add插入元素會拋出java.lang.IllegalStateException: Queue full異常。
    當阻塞隊列空時,再往隊列里remove移除元素會拋出Exception in thread “main” java.util.NoSuchElementException異常。

  • 2. 阻塞隊列api之返回布爾值組

    代碼:

    public static void main(String[] args) throws InterruptedException { System.out.println(blockingQueue.offer("a"));BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);System.out.println("添加元素"+blockingQueue.offer("a"));System.out.println("添加元素"+blockingQueue.offer("b"));System.out.println("添加元素"+blockingQueue.offer("c"));System.out.println("添加元素"+blockingQueue.offer("a"));System.out.println("隊列首個元素:"+blockingQueue.peek());System.out.println("移除元素"+blockingQueue.poll());System.out.println("移除元素"+blockingQueue.poll());System.out.println("移除元素"+blockingQueue.poll());System.out.println("移除元素"+blockingQueue.poll());

    2.1 執行結果:

    2.2 小結:

  • 插入方法,成功ture,失敗false
  • 移除方法,成功返回出隊列的元素,隊列里沒有就返回null

  • 3. 阻塞隊列api之阻塞

    代碼:

    public static void main(String[] args) throws InterruptedException {BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);blockingQueue.put("a");blockingQueue.put("a");blockingQueue.put("a");//blockingQueue.put("a");System.out.println("==================");blockingQueue.take();blockingQueue.take();blockingQueue.take();//blockingQueue.take();}

    當打開注釋blockingQueue.put("a");或者blockingQueue.take();
    執行結果:

    小結:

  • 當阻塞隊列滿時,生產者線程繼續往隊列里put元素,隊列會一直阻塞生產線程直到put數據或者響應中斷退出。
  • 當阻塞隊列空時,消費者線程試圖從隊列里take元素,隊列會一直阻塞消費者線程直到隊列可用。

  • 4. 阻塞隊列api之超時控制

    代碼:

    public static void main(String[] args) throws InterruptedException {BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);System.out.println(blockingQueue.offer("a", 2, TimeUnit.SECONDS));System.out.println(blockingQueue.offer("a", 2, TimeUnit.SECONDS));System.out.println(blockingQueue.offer("a", 2, TimeUnit.SECONDS));System.out.println(blockingQueue.offer("a", 2, TimeUnit.SECONDS));}

    執行結果:


    先阻塞兩秒鐘,2秒后自動結束


    4. SynchronousQueue的用法

  • 與其他BlockingQueue不同,SynchronousQueue是一個不存儲元素的BlockingQueue。每一個put操作必須要等待一個take操作,否則不能繼續添加元素,反之亦然。
  • 代碼實例:

    public static void main(String[] args) throws Exception {BlockingQueue<String> blockingQueue = new SynchronousQueue<>();new Thread(() -> {try {System.out.println(Thread.currentThread().getName()+"\t put 1");blockingQueue.put("1");System.out.println(Thread.currentThread().getName()+"\t put 2");blockingQueue.put("2");System.out.println(Thread.currentThread().getName()+"\t put 3");blockingQueue.put("3");}catch (Exception e){e.printStackTrace();}},"AAA").start();new Thread(() -> {try {//暫停一會線程try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"\t"+blockingQueue.take());try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"\t"+blockingQueue.take());try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"\t"+blockingQueue.take());}catch (Exception e){e.printStackTrace();}},"BBB").start();}

    執行結果:


    5. 用在哪里

    主要用在:

  • 生產者消費者模式(阻塞隊列版)
  • 線程池
  • 消息中間件
  • 等后面寫完了再補上鏈接

    總結

    以上是生活随笔為你收集整理的Java并发编程之阻塞队列的全部內容,希望文章能夠幫你解決所遇到的問題。

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