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

java中阻塞隊(duì)列和非阻塞隊(duì)列的實(shí)現(xiàn)

 更新時(shí)間:2024年10月13日 09:35:24   作者:Flying_Fish_Xuan  
在Java并發(fā)編程中,阻塞隊(duì)列和非阻塞隊(duì)列是兩種主要的隊(duì)列類型,分別適用于不同的場(chǎng)景,了解這兩種隊(duì)列的特點(diǎn)和工作機(jī)制,可以幫助開(kāi)發(fā)者更好地選擇合適的數(shù)據(jù)結(jié)構(gòu)解決并發(fā)問(wèn)題

在 Java 中,**阻塞隊(duì)列(Blocking Queue)非阻塞隊(duì)列(Non-Blocking Queue)**是兩種用于并發(fā)編程的隊(duì)列類型,它們?cè)诙嗑€程環(huán)境中有不同的行為和用途。它們的主要區(qū)別在于對(duì)操作的處理方式:阻塞隊(duì)列在操作無(wú)法立即完成時(shí)會(huì)阻塞線程,而非阻塞隊(duì)列則立即返回或進(jìn)行其他操作。

1. 什么是阻塞隊(duì)列?

阻塞隊(duì)列(Blocking Queue)是一種線程安全的隊(duì)列,它在 Java 中位于 java.util.concurrent 包中。阻塞隊(duì)列支持在隊(duì)列為空時(shí)自動(dòng)等待(即阻塞)直到有元素可以消費(fèi),或者在隊(duì)列已滿時(shí)自動(dòng)等待直到有空間可以插入新元素。這種行為使得阻塞隊(duì)列在生產(chǎn)者-消費(fèi)者模型中非常有用。

阻塞隊(duì)列的操作包括阻塞的插入操作阻塞的刪除操作。它們的主要方法有:

  • put(E e):如果隊(duì)列已滿,當(dāng)前線程將被阻塞,直到隊(duì)列有可用空間。
  • take():如果隊(duì)列為空,當(dāng)前線程將被阻塞,直到隊(duì)列中有可用元素。

Java 中常用的阻塞隊(duì)列有以下幾種:

  • ArrayBlockingQueue:一個(gè)有界的阻塞隊(duì)列,基于數(shù)組實(shí)現(xiàn)。固定大小,支持公平性設(shè)置。

  • LinkedBlockingQueue:一個(gè)可選有界的阻塞隊(duì)列,基于鏈表實(shí)現(xiàn)。默認(rèn)大小為 Integer.MAX_VALUE,適用于任務(wù)生產(chǎn)和消費(fèi)速率不同的場(chǎng)景。

  • PriorityBlockingQueue:一個(gè)支持優(yōu)先級(jí)排序的無(wú)界阻塞隊(duì)列,基于堆實(shí)現(xiàn),元素按優(yōu)先級(jí)順序出隊(duì)。

  • DelayQueue:一個(gè)支持延遲獲取元素的無(wú)界阻塞隊(duì)列,只有在元素的延遲期滿后才能從隊(duì)列中獲取元素。

  • SynchronousQueue:一個(gè)不存儲(chǔ)元素的阻塞隊(duì)列,每個(gè)插入操作必須等待一個(gè)相應(yīng)的刪除操作。適用于交換場(chǎng)景。

2. 什么是非阻塞隊(duì)列?

非阻塞隊(duì)列(Non-Blocking Queue)是一種不進(jìn)行阻塞的線程安全隊(duì)列。非阻塞隊(duì)列不等待當(dāng)前線程完成操作,而是立即返回或執(zhí)行其他操作。它們通常使用 CAS(Compare-And-Swap) 操作來(lái)確保線程安全性,從而避免線程在等待鎖時(shí)發(fā)生阻塞。

非阻塞隊(duì)列的操作包括非阻塞的插入操作非阻塞的刪除操作。它們的主要方法有:

  • offer(E e):嘗試插入元素到隊(duì)列中,如果成功則返回 true,如果隊(duì)列已滿則立即返回 false。
  • poll():嘗試從隊(duì)列中取出一個(gè)元素,如果成功則返回元素,如果隊(duì)列為空則立即返回 null。

Java 中常用的非阻塞隊(duì)列有:

  • ConcurrentLinkedQueue:一個(gè)基于鏈表的無(wú)界非阻塞隊(duì)列,使用 CAS 操作來(lái)實(shí)現(xiàn)線程安全。適用于高并發(fā)場(chǎng)景。

  • ConcurrentLinkedDeque:一個(gè)雙端非阻塞隊(duì)列,基于鏈表實(shí)現(xiàn),支持在隊(duì)列的兩端進(jìn)行插入和刪除操作。

3. 阻塞隊(duì)列和非阻塞隊(duì)列的區(qū)別

  • 阻塞與非阻塞:阻塞隊(duì)列在讀取或?qū)懭霑r(shí)可能會(huì)發(fā)生阻塞,而普通隊(duì)列則不會(huì)發(fā)生這種情況。當(dāng)一個(gè)線程嘗試從空的普通隊(duì)列中讀取數(shù)據(jù)或向已滿的普通隊(duì)列中寫(xiě)入數(shù)據(jù)時(shí),它將直接返回一個(gè)特定的值,而不是等待其他線程的操作。

  • 同步與異步:阻塞隊(duì)列通常用于同步處理場(chǎng)景,而普通隊(duì)列通常用于異步處理場(chǎng)景。在同步處理場(chǎng)景下,多個(gè)線程之間需要協(xié)調(diào)工作,而在異步處理場(chǎng)景下,多個(gè)線程之間可以獨(dú)立地進(jìn)行各自的任務(wù)

  • 性能差異:由于阻塞隊(duì)列使用了鎖機(jī)制,所以在高并發(fā)情況下可能會(huì)出現(xiàn)性能瓶頸;而非阻塞隊(duì)列使用了原子操作和CAS指令,因此在高并發(fā)情況下具有更好的性能表現(xiàn)。

4. 使用場(chǎng)景和選擇指南

阻塞隊(duì)列和非阻塞隊(duì)列各自適用于不同的場(chǎng)景。了解它們的特點(diǎn)和工作機(jī)制可以幫助開(kāi)發(fā)者更好地選擇合適的數(shù)據(jù)結(jié)構(gòu)來(lái)解決并發(fā)問(wèn)題。

4.1 阻塞隊(duì)列的使用場(chǎng)景

  • 生產(chǎn)者-消費(fèi)者模型:阻塞隊(duì)列最常見(jiàn)的應(yīng)用場(chǎng)景就是生產(chǎn)者-消費(fèi)者模型。在這種模型中,生產(chǎn)者線程不斷地將任務(wù)放入隊(duì)列,消費(fèi)者線程不斷地從隊(duì)列中取任務(wù)。使用阻塞隊(duì)列可以避免生產(chǎn)者或消費(fèi)者線程在隊(duì)列為空或已滿時(shí)的忙等待,從而提高系統(tǒng)性能。

  • 任務(wù)調(diào)度和工作線程池:在任務(wù)調(diào)度系統(tǒng)或工作線程池中,阻塞隊(duì)列可以用于存放任務(wù)。線程池的工作線程可以從隊(duì)列中取任務(wù)并執(zhí)行,如果沒(méi)有任務(wù)則自動(dòng)等待直到有新任務(wù)到來(lái)。

  • 延遲任務(wù)執(zhí)行DelayQueue 適用于需要在一定延遲后執(zhí)行任務(wù)的場(chǎng)景,例如定時(shí)任務(wù)調(diào)度。

4.2 非阻塞隊(duì)列的使用場(chǎng)景

  • 高并發(fā)場(chǎng)景:非阻塞隊(duì)列通常用于需要高并發(fā)訪問(wèn)的場(chǎng)景,因?yàn)樗皇褂面i而是依賴 CAS 操作來(lái)確保線程安全,從而減少了鎖競(jìng)爭(zhēng)的開(kāi)銷,能夠提供更高的吞吐量。

  • 低延遲應(yīng)用:對(duì)于需要快速響應(yīng)、低延遲的應(yīng)用,非阻塞隊(duì)列是非常適合的選擇。例如,在金融交易系統(tǒng)或高性能計(jì)算系統(tǒng)中,需要非??焖俚靥幚碚?qǐng)求而不受鎖的影響。

  • 無(wú)界隊(duì)列:非阻塞隊(duì)列通常是無(wú)界的,例如 ConcurrentLinkedQueue,這意味著它們不會(huì)限制隊(duì)列大小,但要小心使用,避免內(nèi)存溢出。

5. 阻塞隊(duì)列和非阻塞隊(duì)列的實(shí)現(xiàn)原理

5.1 阻塞隊(duì)列的實(shí)現(xiàn)原理

阻塞隊(duì)列的實(shí)現(xiàn)依賴于內(nèi)部鎖和條件變量(Condition)來(lái)實(shí)現(xiàn)線程同步。例如,ArrayBlockingQueue 的實(shí)現(xiàn)如下:

  • 插入操作put():如果隊(duì)列已滿,插入線程會(huì)被放入“等待可用空間”的條件隊(duì)列中,直到有其他線程取走元素并喚醒它。
  • 取出操作(take():如果隊(duì)列為空,取出線程會(huì)被放入“等待元素”的條件隊(duì)列中,直到有其他線程插入元素并喚醒它。

這些方法通過(guò) ReentrantLock 和 Condition 來(lái)實(shí)現(xiàn)同步控制:

public void put(E e) throws InterruptedException {
    final ReentrantLock lock = this.lock;
    lock.lockInterruptibly();
    try {
        while (count == items.length)
            notFull.await();  // 等待隊(duì)列非滿
        enqueue(e);
    } finally {
        lock.unlock();
    }
}

5.2 非阻塞隊(duì)列的實(shí)現(xiàn)原理

非阻塞隊(duì)列通常使用 CAS(Compare-And-Swap)操作來(lái)實(shí)現(xiàn)線程安全。ConcurrentLinkedQueue 是一個(gè)典型的非阻塞隊(duì)列,它通過(guò)鏈表的方式實(shí)現(xiàn)。其 offer() 和 poll() 方法實(shí)現(xiàn)如下:

  • 插入操作(offer():使用 CAS 操作來(lái)將新節(jié)點(diǎn)插入到鏈表的末尾。如果失敗則不斷重試,直到成功為止。

  • 取出操作(poll():使用 CAS 操作來(lái)獲取并移除鏈表的頭節(jié)點(diǎn),同樣會(huì)在操作失敗時(shí)進(jìn)行重試,直到成功。

public boolean offer(E e) {
    final Node<E> newNode = new Node<>(e);
    for (Node<E> t = tail, p = t;;) {
        Node<E> q = p.next;
        if (q

 == null) {
            if (p.casNext(null, newNode)) {
                if (p != t)
                    casTail(t, newNode);  // 使用 CAS 更新尾節(jié)點(diǎn)
                return true;
            }
        } else if (p == q)
            p = (t != (t = tail)) ? t : head;
        else
            p = (p != t && t != (t = tail)) ? t : q;
    }
}

6. 示例代碼

下面是一個(gè)使用阻塞隊(duì)列和非阻塞隊(duì)列的簡(jiǎn)單示例:

阻塞隊(duì)列示例:ArrayBlockingQueue

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class BlockingQueueExample {
    public static void main(String[] args) throws InterruptedException {
        BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(5);

        // 生產(chǎn)者線程
        Thread producer = new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    System.out.println("生產(chǎn)者生產(chǎn): " + i);
                    queue.put(i);  // 阻塞插入操作
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });

        // 消費(fèi)者線程
        Thread consumer = new Thread(() -> {
            try {
                while (true) {
                    Integer item = queue.take();  // 阻塞取出操作
                    System.out.println("消費(fèi)者消費(fèi): " + item);
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });

        producer.start();
        consumer.start();
    }
}

非阻塞隊(duì)列示例:ConcurrentLinkedQueue

import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

public class NonBlockingQueueExample {
    public static void main(String[] args) {
        Queue<Integer> queue = new ConcurrentLinkedQueue<>();

        // 添加元素
        queue.offer(1);
        queue.offer(2);
        queue.offer(3);

        // 取出元素
        Integer item;
        while ((item = queue.poll()) != null) {
            System.out.println("取出: " + item);
        }
    }
}

7. 總結(jié)

阻塞隊(duì)列和非阻塞隊(duì)列在 Java 并發(fā)編程中具有不同的應(yīng)用場(chǎng)景和特點(diǎn)。阻塞隊(duì)列通過(guò)內(nèi)部鎖和條件變量實(shí)現(xiàn)線程安全,適用于生產(chǎn)者-消費(fèi)者模型和任務(wù)調(diào)度等場(chǎng)景。非阻塞隊(duì)列通過(guò) CAS 操作實(shí)現(xiàn)線程安全,適用于高并發(fā)和低延遲場(chǎng)景。

到此這篇關(guān)于java中阻塞隊(duì)列和非阻塞隊(duì)列的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)java 阻塞隊(duì)列和非阻塞隊(duì)列內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot集成Shiro進(jìn)行權(quán)限控制和管理的示例

    SpringBoot集成Shiro進(jìn)行權(quán)限控制和管理的示例

    這篇文章主要介紹了SpringBoot集成Shiro進(jìn)行權(quán)限控制和管理的示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-03-03
  • java實(shí)現(xiàn)多線程交替打印

    java實(shí)現(xiàn)多線程交替打印

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)多線程交替打印,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • java轉(zhuǎn)換字符串編碼格式的方法

    java轉(zhuǎn)換字符串編碼格式的方法

    這篇文章主要介紹了java轉(zhuǎn)換字符串編碼格式的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08
  • 全解史上最快的JOSN解析庫(kù)alibaba Fastjson

    全解史上最快的JOSN解析庫(kù)alibaba Fastjson

    這篇文章主要介紹了史上最快的JOSN解析庫(kù)alibaba Fastjson,對(duì)FastJson感興趣的同學(xué),一定要看一下
    2021-04-04
  • java web返回中文亂碼問(wèn)題及解決

    java web返回中文亂碼問(wèn)題及解決

    這篇文章主要介紹了java web返回中文亂碼問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • Spring Native項(xiàng)目實(shí)戰(zhàn)(體驗(yàn)79毫秒啟動(dòng)springboot應(yīng)用)

    Spring Native項(xiàng)目實(shí)戰(zhàn)(體驗(yàn)79毫秒啟動(dòng)springboot應(yīng)用)

    Spring Native是Spring提供的、制作native image的技術(shù)方案,本篇主要內(nèi)容是開(kāi)發(fā)springboot應(yīng)用再構(gòu)建為native image的方法,通過(guò)Spring Native項(xiàng)目實(shí)戰(zhàn)讓大家體驗(yàn)79毫秒啟動(dòng)springboot應(yīng)用,感興趣的朋友跟隨小編一起看看吧
    2021-05-05
  • Spring注解 TX聲明式事務(wù)實(shí)現(xiàn)過(guò)程解析

    Spring注解 TX聲明式事務(wù)實(shí)現(xiàn)過(guò)程解析

    這篇文章主要介紹了Spring注解 - TX 聲明式事務(wù)實(shí)現(xiàn)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • java合并多個(gè)文件的兩種方法

    java合并多個(gè)文件的兩種方法

    這篇文章主要為大家詳細(xì)介紹了java合并多個(gè)文件的兩種方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • SpringBoot如何訪問(wèn)本地圖片

    SpringBoot如何訪問(wèn)本地圖片

    這篇文章主要介紹了SpringBoot如何訪問(wèn)本地圖片問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • Java之JSF框架案例詳解

    Java之JSF框架案例詳解

    這篇文章主要介紹了Java之JSF框架案例詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-09-09

最新評(píng)論