最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java 的 Condition 接口與等待通知機(jī)制詳解

 更新時(shí)間:2025年05月21日 14:46:14   作者:潛意識(shí)Java  
在 Java 并發(fā)編程里,實(shí)現(xiàn)線程間的協(xié)作與同步是極為關(guān)鍵的任務(wù),本文將深入探究Condition接口及其背后的等待通知機(jī)制,感興趣的朋友一起看看吧

一、引言

在 Java 并發(fā)編程里,實(shí)現(xiàn)線程間的協(xié)作與同步是極為關(guān)鍵的任務(wù)。除了使用 Object 類的 wait()、notify() 和 notifyAll() 方法實(shí)現(xiàn)簡單的等待 - 通知機(jī)制外,Java 還提供了 Condition 接口,它與 ReentrantLock 配合使用,能實(shí)現(xiàn)更靈活、更精細(xì)的線程間通信。本文將深入探究 Condition 接口及其背后的等待通知機(jī)制。

二、Condition 接口概述

2.1 基本概念

Condition 接口位于 java.util.concurrent.locks 包中,它提供了類似 Object 類的 wait()、notify() 和 notifyAll() 方法的功能,但 Condition 更為強(qiáng)大和靈活。Condition 實(shí)例是通過 Lock 對(duì)象的 newCondition() 方法創(chuàng)建的,每個(gè) Lock 對(duì)象可以創(chuàng)建多個(gè) Condition 實(shí)例,這使得我們可以針對(duì)不同的條件進(jìn)行線程的等待和喚醒操作。

2.2 與 Object 類等待通知方法的區(qū)別

  • 關(guān)聯(lián)對(duì)象不同Object 類的 wait()、notify() 和 notifyAll() 方法必須在 synchronized 塊或方法中使用,它們關(guān)聯(lián)的是對(duì)象的內(nèi)部鎖;而 Condition 接口的方法(如 await()、signal() 和 signalAll())必須與 Lock 對(duì)象配合使用,關(guān)聯(lián)的是 Lock 對(duì)象。
  • 靈活性不同Condition 可以創(chuàng)建多個(gè)等待隊(duì)列,允許更細(xì)粒度的線程控制。例如,一個(gè)線程可以等待某個(gè)特定的條件,而另一個(gè)線程可以喚醒等待該條件的線程,而 Object 類的等待通知方法只能操作一個(gè)隱含的等待隊(duì)列。

三、Condition 接口的常用方法

3.1 await () 方法

await() 方法會(huì)使當(dāng)前線程進(jìn)入等待狀態(tài),直到其他線程調(diào)用該 Condition 的 signal() 或 signalAll() 方法,或者當(dāng)前線程被中斷。調(diào)用 await() 方法時(shí),當(dāng)前線程會(huì)釋放持有的 Lock,在被喚醒后,會(huì)重新獲取該 Lock。示例代碼如下:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class AwaitExample {
    private final Lock lock = new ReentrantLock();
    private final Condition condition = lock.newCondition();
    public void awaitMethod() {
        lock.lock();
        try {
            System.out.println("Thread " + Thread.currentThread().getName() + " is waiting.");
            condition.await();
            System.out.println("Thread " + Thread.currentThread().getName() + " is awakened.");
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            lock.unlock();
        }
    }
}

3.2 signal () 方法

signal() 方法會(huì)喚醒在該 Condition 上等待的單個(gè)線程。如果有多個(gè)線程在等待,只會(huì)喚醒其中一個(gè)線程,具體喚醒哪個(gè)線程是不確定的。示例代碼如下:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class SignalExample {
    private final Lock lock = new ReentrantLock();
    private final Condition condition = lock.newCondition();
    public void signalMethod() {
        lock.lock();
        try {
            System.out.println("Thread " + Thread.currentThread().getName() + " is signaling.");
            condition.signal();
        } finally {
            lock.unlock();
        }
    }
}

3.3 signalAll () 方法

signalAll() 方法會(huì)喚醒在該 Condition 上等待的所有線程。被喚醒的線程會(huì)競爭獲取 Lock,獲取到 Lock 的線程將繼續(xù)執(zhí)行。示例代碼如下:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class SignalAllExample {
    private final Lock lock = new ReentrantLock();
    private final Condition condition = lock.newCondition();
    public void signalAllMethod() {
        lock.lock();
        try {
            System.out.println("Thread " + Thread.currentThread().getName() + " is signaling all.");
            condition.signalAll();
        } finally {
            lock.unlock();
        }
    }
}

四、Condition 接口的應(yīng)用場景

4.1 生產(chǎn)者 - 消費(fèi)者模式

使用 Condition 接口可以實(shí)現(xiàn)更復(fù)雜的生產(chǎn)者 - 消費(fèi)者模式。例如,當(dāng)緩沖區(qū)滿時(shí),生產(chǎn)者線程等待;當(dāng)緩沖區(qū)為空時(shí),消費(fèi)者線程等待。示例代碼如下:

import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class Buffer {
    private final LinkedList<Integer> buffer = new LinkedList<>();
    private static final int MAX_SIZE = 5;
    private final Lock lock = new ReentrantLock();
    private final Condition notFull = lock.newCondition();
    private final Condition notEmpty = lock.newCondition();
    public void produce(int item) {
        lock.lock();
        try {
            while (buffer.size() == MAX_SIZE) {
                System.out.println("Buffer is full, producer is waiting.");
                notFull.await();
            }
            buffer.add(item);
            System.out.println("Produced: " + item);
            notEmpty.signal();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            lock.unlock();
        }
    }
    public int consume() {
        lock.lock();
        try {
            while (buffer.size() == 0) {
                System.out.println("Buffer is empty, consumer is waiting.");
                notEmpty.await();
            }
            int item = buffer.removeFirst();
            System.out.println("Consumed: " + item);
            notFull.signal();
            return item;
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return -1;
        } finally {
            lock.unlock();
        }
    }
}
public class ProducerConsumerWithCondition {
    public static void main(String[] args) {
        Buffer buffer = new Buffer();
        Thread producer = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                buffer.produce(i);
            }
        });
        Thread consumer = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                buffer.consume();
            }
        });
        producer.start();
        consumer.start();
    }
}

4.2 多線程任務(wù)協(xié)調(diào)

在一些多線程任務(wù)中,需要根據(jù)不同的條件來協(xié)調(diào)線程的執(zhí)行順序。例如,一個(gè)線程需要等待其他幾個(gè)線程完成特定任務(wù)后才能繼續(xù)執(zhí)行,這時(shí)可以使用 Condition 接口來實(shí)現(xiàn)。

五、Condition 接口的實(shí)現(xiàn)原理

Condition 接口的實(shí)現(xiàn)通常依賴于 AbstractQueuedSynchronizer(AQS)。每個(gè) Condition 實(shí)例都有一個(gè)與之關(guān)聯(lián)的等待隊(duì)列,當(dāng)線程調(diào)用 await() 方法時(shí),會(huì)將該線程封裝成一個(gè)節(jié)點(diǎn)加入到等待隊(duì)列中,并釋放持有的 Lock。當(dāng)其他線程調(diào)用 signal() 或 signalAll() 方法時(shí),會(huì)從等待隊(duì)列中移除相應(yīng)的節(jié)點(diǎn),并將其加入到 Lock 的同步隊(duì)列中,等待獲取 Lock。

六、使用 Condition 接口的注意事項(xiàng)

6.1 鎖的獲取和釋放

在調(diào)用 Condition 接口的方法之前,必須先獲取關(guān)聯(lián)的 Lock,并且在使用完后要確保釋放 Lock,通常使用 try - finally 塊來保證這一點(diǎn)。

6.2 中斷處理

await() 方法會(huì)拋出 InterruptedException 異常,因此需要在代碼中進(jìn)行適當(dāng)?shù)漠惓L幚?,以確保線程在被中斷時(shí)能夠正確響應(yīng)。

6.3 條件判斷

在調(diào)用 await() 方法時(shí),通常需要使用 while 循環(huán)來進(jìn)行條件判斷,而不是 if 語句。這是因?yàn)樵诙嗑€程環(huán)境下,線程被喚醒后可能會(huì)出現(xiàn)虛假喚醒的情況,使用 while 循環(huán)可以確保條件仍然滿足。

七、總結(jié)

Condition 接口為 Java 并發(fā)編程提供了一種強(qiáng)大而靈活的線程間等待通知機(jī)制。通過與 ReentrantLock 配合使用,可以實(shí)現(xiàn)更復(fù)雜、更精細(xì)的線程同步和協(xié)作。在實(shí)際開發(fā)中,根據(jù)具體的業(yè)務(wù)需求合理使用 Condition 接口,能夠提高程序的并發(fā)性能和可靠性。同時(shí),需要注意鎖的獲取和釋放、中斷處理以及條件判斷等問題,以避免出現(xiàn)并發(fā)問題。

到此這篇關(guān)于探究 Java 的 Condition 接口與等待通知機(jī)制的文章就介紹到這了,更多相關(guān)java condition 等待通知機(jī)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java讀取Excel、docx、pdf和txt等文件萬能方法舉例

    Java讀取Excel、docx、pdf和txt等文件萬能方法舉例

    在Java開發(fā)中處理文件是常見需求,本文以實(shí)際代碼示例詳述如何使用ApachePOI庫及其他工具讀取和寫入Excel、Word、PDF等文件,介紹了ApachePOI、ApachePDFBox和EasyExcel等庫的使用方法,幫助開發(fā)者有效讀取不同格式文件,需要的朋友可以參考下
    2024-09-09
  • Nacos?動(dòng)態(tài)服務(wù)發(fā)現(xiàn)、配置和服務(wù)管理平臺(tái)初體驗(yàn)

    Nacos?動(dòng)態(tài)服務(wù)發(fā)現(xiàn)、配置和服務(wù)管理平臺(tái)初體驗(yàn)

    這篇文章主要介紹了Nacos?動(dòng)態(tài)服務(wù)發(fā)現(xiàn)、配置和服務(wù)管理平臺(tái)初體驗(yàn)的相關(guān)資料,需要的朋友可以參考下
    2022-09-09
  • Java使用arthas修改日志級(jí)別詳解

    Java使用arthas修改日志級(jí)別詳解

    在我們線上環(huán)境中,一般不會(huì)開啟debug級(jí)別的日志,為了提高性能?info和warning級(jí)別的日志也一般不會(huì)打印出來,那么如果遇到線上問題,除了使用arthas定位問題,想通過查詢?nèi)罩緛韺?shí)現(xiàn)問題定位,如何查看logger信息,更新logger?level呢,下面我們來了解arthas修改日志級(jí)別
    2022-06-06
  • Java面試題沖刺第二十二天-- Nginx

    Java面試題沖刺第二十二天-- Nginx

    這篇文章主要為大家分享了最有價(jià)值的三道關(guān)于Nginx的面試題,涵蓋內(nèi)容全面,包括數(shù)據(jù)結(jié)構(gòu)和算法相關(guān)的題目、經(jīng)典面試編程題等,感興趣的小伙伴們可以參考一下
    2021-08-08
  • java集合中HashSet LinkedHashSet TreeSet三者異同面試精講

    java集合中HashSet LinkedHashSet TreeSet三者異同面試精講

    這篇文章主要為大家介紹了java集合中HashSet LinkedHashSet TreeSet三者異同面試精講,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • SpringBoot使用Validator進(jìn)行參數(shù)校驗(yàn)實(shí)戰(zhàn)教程(自定義校驗(yàn),分組校驗(yàn))

    SpringBoot使用Validator進(jìn)行參數(shù)校驗(yàn)實(shí)戰(zhàn)教程(自定義校驗(yàn),分組校驗(yàn))

    這篇文章主要介紹了SpringBoot使用Validator進(jìn)行參數(shù)校驗(yàn)(自定義校驗(yàn),分組校驗(yàn))的實(shí)戰(zhàn)教程,本文通過示例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2023-07-07
  • Mybatis-Plus支持GBase8s分頁查詢的實(shí)現(xiàn)示例

    Mybatis-Plus支持GBase8s分頁查詢的實(shí)現(xiàn)示例

    本文主要介紹了使?Mybatis-Plus?支持?GBase8s?的分頁查詢,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • 解決java.lang.StringIndexOutOfBoundsException: String index out of range: -1錯(cuò)誤問題

    解決java.lang.StringIndexOutOfBoundsException: String&nbs

    這篇文章主要介紹了解決java.lang.StringIndexOutOfBoundsException: String index out of range: -1錯(cuò)誤問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-03-03
  • Java中super關(guān)鍵字的用法和細(xì)節(jié)

    Java中super關(guān)鍵字的用法和細(xì)節(jié)

    大家好,本篇文章主要講的是Java中super關(guān)鍵字的用法和細(xì)節(jié),感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下
    2022-01-01
  • Java參數(shù)傳遞實(shí)現(xiàn)代碼及過程圖解

    Java參數(shù)傳遞實(shí)現(xiàn)代碼及過程圖解

    這篇文章主要介紹了Java參數(shù)傳遞實(shí)現(xiàn)代碼及過程圖解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11

最新評(píng)論

四川省| 巴林左旗| 鱼台县| 达日县| 兰坪| 四会市| 社会| 旌德县| 江门市| 孟州市| 师宗县| 瓮安县| 邵武市| 武平县| 德令哈市| 逊克县| 商洛市| 大名县| 甘肃省| 陕西省| 华宁县| 彰武县| 大埔县| 高密市| 道孚县| 栾城县| 肥城市| 新营市| 祁东县| 唐海县| 富裕县| 丹阳市| 东明县| 若羌县| 如皋市| 荣成市| 高台县| 沾化县| 丘北县| 泰安市| 祁东县|