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

Java并發(fā)之Condition案例詳解

 更新時間:2021年09月01日 11:45:20   作者:數(shù)月亮  
這篇文章主要介紹了Java并發(fā)之Condition案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下

在使用Lock之前,我們使用的最多的同步方式應(yīng)該是synchronized關(guān)鍵字來實現(xiàn)同步方式了。配合Object的wait()、notify()系列方法可以實現(xiàn)等待/通知模式。Condition接口也提供了類似Object的監(jiān)視器方法,與Lock配合可以實現(xiàn)等待/通知模式,但是這兩者在使用方式以及功能特性上還是有差別的。Object和Condition接口的一些對比。摘自《Java并發(fā)編程的藝術(shù)》

image

一、Condition接口介紹和示例

        首先我們需要明白condition對象是依賴于lock對象的,意思就是說condition對象需要通過lock對象進行創(chuàng)建出來(調(diào)用Lock對象的newCondition()方法)。consition的使用方式非常的簡單。但是需要注意在調(diào)用方法前獲取鎖。

package com.ydl.test.juc;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ConditionUseCase {

    public Lock lock = new ReentrantLock();
    public Condition condition = lock.newCondition();

    public static void main(String[] args)  {
        ConditionUseCase useCase = new ConditionUseCase();
        ExecutorService executorService = Executors.newFixedThreadPool (2);
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                useCase.conditionWait();
            }
        });
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                useCase.conditionSignal();
            }
        });
    }

    public void conditionWait()  {
        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName() + "拿到鎖了");
            System.out.println(Thread.currentThread().getName() + "等待信號");
            condition.await();
            System.out.println(Thread.currentThread().getName() + "拿到信號");
        }catch (Exception e){

        }finally {
            lock.unlock();
        }
    }
    public void conditionSignal() {
        lock.lock();
        try {
            Thread.sleep(5000);
            System.out.println(Thread.currentThread().getName() + "拿到鎖了");
            condition.signal();
            System.out.println(Thread.currentThread().getName() + "發(fā)出信號");
        }catch (Exception e){

        }finally {
            lock.unlock();
        }
    }

}

1 pool-1-thread-1拿到鎖了

2 pool-1-thread-1等待信號
3 pool-1-thread-2拿到鎖了
4 pool-1-thread-2發(fā)出信號 

如示例所示,一般都會將Condition對象作為成員變量。當調(diào)用await()方法后,當前線程會釋放鎖并在此等待,而其他線程調(diào)用Condition對象的signal()方法,通知當前線程后,當前線程才從await()方法返回,并且在返回前已經(jīng)獲取了鎖。

二、Condition接口常用方法

        condition可以通俗的理解為條件隊列。當一個線程在調(diào)用了await方法以后,直到線程等待的某個條件為真的時候才會被喚醒。這種方式為線程提供了更加簡單的等待/通知模式。Condition必須要配合鎖一起使用,因為對共享狀態(tài)變量的訪問發(fā)生在多線程環(huán)境下。一個Condition的實例必須與一個Lock綁定,因此Condition一般都是作為Lock的內(nèi)部實現(xiàn)。

  1. await() :造成當前線程在接到信號或被中斷之前一直處于等待狀態(tài)。
  2. await(long time, TimeUnit unit) :造成當前線程在接到信號、被中斷或到達指定等待時間之前一直處于等待狀態(tài)。
  3. awaitNanos(long nanosTimeout) :造成當前線程在接到信號、被中斷或到達指定等待時間之前一直處于等待狀態(tài)。返回值表示剩余時間,如果在nanosTimesout之前喚醒,那么返回值 = nanosTimeout - 消耗時間,如果返回值 <= 0 ,則可以認定它已經(jīng)超時了。
  4. awaitUninterruptibly() :造成當前線程在接到信號之前一直處于等待狀態(tài)?!咀⒁猓涸摲椒▽χ袛嗖幻舾小俊?/li>
  5. awaitUntil(Date deadline) :造成當前線程在接到信號、被中斷或到達指定最后期限之前一直處于等待狀態(tài)。如果沒有到指定時間就被通知,則返回true,否則表示到了指定時間,返回返回false。
  6. signal() :喚醒一個等待線程。該線程從等待方法返回前必須獲得與Condition相關(guān)的鎖。
  7. signal()All :喚醒所有等待線程。能夠從等待方法返回的線程必須獲得與Condition相關(guān)的鎖。

三、Condition接口原理簡單解析

        Condition是AQS的內(nèi)部類。每個Condition對象都包含一個隊列(等待隊列)。等待隊列是一個FIFO的隊列,在隊列中的每個節(jié)點都包含了一個線程引用,該線程就是在Condition對象上等待的線程,如果一個線程調(diào)用了Condition.await()方法,那么該線程將會釋放鎖、構(gòu)造成節(jié)點加入等待隊列并進入等待狀態(tài)。等待隊列的基本結(jié)構(gòu)如下所示。

image

等待分為首節(jié)點和尾節(jié)點。當一個線程調(diào)用Condition.await()方法,將會以當前線程構(gòu)造節(jié)點,并將節(jié)點從尾部加入等待隊列。新增節(jié)點就是將尾部節(jié)點指向新增的節(jié)點。節(jié)點引用更新本來就是在獲取鎖以后的操作,所以不需要CAS保證。同時也是線程安全的操作。

3.1、等待

當線程調(diào)用了await方法以后。線程就作為隊列中的一個節(jié)點被加入到等待隊列中去了。同時會釋放鎖的擁有。當從await方法返回的時候。一定會獲取condition相關(guān)聯(lián)的鎖。當?shù)却犃兄械墓?jié)點被喚醒的時候,則喚醒節(jié)點的線程開始嘗試獲取同步狀態(tài)。如果不是通過 其他線程調(diào)用Condition.signal()方法喚醒,而是對等待線程進行中斷,則會拋出InterruptedException異常信息。

3.2、通知

調(diào)用Condition的signal()方法,將會喚醒在等待隊列中等待最長時間的節(jié)點(條件隊列里的首節(jié)點),在喚醒節(jié)點前,會將節(jié)點移到同步隊列中。當前線程加入到等待隊列中如圖所示:

image

在調(diào)用signal()方法之前必須先判斷是否獲取到了鎖。接著獲取等待隊列的首節(jié)點,將其移動到同步隊列并且利用LockSupport喚醒節(jié)點中的線程。節(jié)點從等待隊列移動到同步隊列如下圖所示:

image

被喚醒的線程將從await方法中的while循環(huán)中退出。隨后加入到同步狀態(tài)的競爭當中去。成功獲取到競爭的線程則會返回到await方法之前的狀態(tài)。

四、總結(jié)

調(diào)用await方法后,將當前線程加入Condition等待隊列中。當前線程釋放鎖。否則別的線程就無法拿到鎖而發(fā)生死鎖。自旋(while)掛起,不斷檢測節(jié)點是否在同步隊列中了,如果是則嘗試獲取鎖,否則掛起。當線程被signal方法喚醒,被喚醒的線程將從await()方法中的while循環(huán)中退出來,然后調(diào)用acquireQueued()方法競爭同步狀態(tài)。

五、利用Condition實現(xiàn)生產(chǎn)者消費者模式

import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class BoundedQueue {

    private LinkedList<Object> buffer;    //生產(chǎn)者容器
    private int maxSize ;           //容器最大值是多少
    private Lock lock;
    private Condition fullCondition;
    private Condition notFullCondition;
    BoundedQueue(int maxSize){
        this.maxSize = maxSize;
        buffer = new LinkedList<Object>();
        lock = new ReentrantLock();
        fullCondition = lock.newCondition();
        notFullCondition = lock.newCondition();
    }

    /**
     * 生產(chǎn)者
     * @param obj
     * @throws InterruptedException
     */
    public void put(Object obj) throws InterruptedException {
        lock.lock();    //獲取鎖
        try {
            while (maxSize == buffer.size()){
                notFullCondition.await();       //滿了,添加的線程進入等待狀態(tài)
            }
            buffer.add(obj);
            fullCondition.signal(); //通知
        } finally {
            lock.unlock();
        }
    }

    /**
     * 消費者
     * @return
     * @throws InterruptedException
     */
    public Object get() throws InterruptedException {
        Object obj;
        lock.lock();
        try {
            while (buffer.size() == 0){ //隊列中沒有數(shù)據(jù)了 線程進入等待狀態(tài)
                fullCondition.await();
            }
            obj = buffer.poll();
            notFullCondition.signal(); //通知
        } finally {
            lock.unlock();
        }
        return obj;
    }

}

到此這篇關(guān)于Java并發(fā)之Condition案例詳解的文章就介紹到這了,更多相關(guān)Java并發(fā)之Condition案例內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中Optional的正確用法與爭議點詳解

    Java中Optional的正確用法與爭議點詳解

    這篇文章主要介紹了Java中Optional的正確用法與爭議點的相關(guān)資料,需要的朋友可以參考下
    2022-11-11
  • 深入淺出Java mvc_動力節(jié)點Java學院整理

    深入淺出Java mvc_動力節(jié)點Java學院整理

    這篇文章主要為大家詳細介紹了MVC的基礎(chǔ)知識,MVC是一個框架模式,它強制性的使應(yīng)用程序的輸入、處理和輸出分開,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • Java selenium處理極驗滑動驗證碼示例

    Java selenium處理極驗滑動驗證碼示例

    本篇文章主要介紹了Java selenium處理極驗滑動驗證碼示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • Java觀察者模式例子

    Java觀察者模式例子

    這篇文章主要介紹了Java觀察者模式例子的相關(guān)資料,需要的朋友可以參考下
    2015-12-12
  • SpringBoot+Mybatis項目使用Redis做Mybatis的二級緩存的方法

    SpringBoot+Mybatis項目使用Redis做Mybatis的二級緩存的方法

    本篇文章主要介紹了SpringBoot+Mybatis項目使用Redis做Mybatis的二級緩存的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • Java File類的簡單使用教程(創(chuàng)建、刪除、遍歷與判斷是否存在等)

    Java File類的簡單使用教程(創(chuàng)建、刪除、遍歷與判斷是否存在等)

    這篇文章主要給大家介紹了關(guān)于Java File類的簡單使用(創(chuàng)建、刪除、遍歷與判斷是否存在等)的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-12-12
  • Java診斷工具Arthas的快速入門與實踐

    Java診斷工具Arthas的快速入門與實踐

    在Java開發(fā)中,我們經(jīng)常會遇到各種性能問題、內(nèi)存泄漏、線程阻塞等問題,這些問題往往難以通過常規(guī)的日志和監(jiān)控工具來定位和解決,Arthas作為一款開源的Java診斷工具,提供了強大的實時監(jiān)控和診斷功能,本文將詳細介紹Arthas的安裝、基本使用以及一些常用命令
    2025-02-02
  • Maven生成可直接運行的jar包(多種方式)

    Maven生成可直接運行的jar包(多種方式)

    文章介紹了三種使用Maven生成可以直接運行的jar包的方法:通過maven-jar-plugin和maven-dependency-plugin插件、maven-assembly-plugin插件以及maven-shade-plugin插件,每種方法都有其特點和適用場景,感興趣的朋友跟隨小編一起看看吧
    2024-11-11
  • Spring?Boot?3中一套可以直接用于生產(chǎn)環(huán)境的Log4J2日志配置詳解

    Spring?Boot?3中一套可以直接用于生產(chǎn)環(huán)境的Log4J2日志配置詳解

    Log4J2是Apache Log4j的升級版,參考了logback的一些優(yōu)秀的設(shè)計,并且修復了一些問題,因此帶來了一些重大的提升,這篇文章主要介紹了Spring?Boot?3中一套可以直接用于生產(chǎn)環(huán)境的Log4J2日志配置,需要的朋友可以參考下
    2023-12-12
  • 在eclipse中中文漢字亂碼的解決方案

    在eclipse中中文漢字亂碼的解決方案

    在本篇文章里小編給大家分享的是關(guān)于在eclipse中中文漢字亂碼的解決方案,有需要的朋友們可以學習下。
    2019-12-12

最新評論

萝北县| 深水埗区| 梓潼县| 盘山县| 华容县| 清远市| 深泽县| 尼玛县| 昭平县| 繁峙县| 拉孜县| 湖州市| 玉林市| 泗洪县| 长治市| 博湖县| 淮安市| 桐柏县| 宁武县| 靖西县| 柯坪县| 嫩江县| 诸城市| 平原县| 姚安县| 土默特右旗| 瓦房店市| 东光县| 宁海县| 深水埗区| 新民市| 邛崃市| 尉氏县| 开鲁县| 余干县| 南靖县| 长泰县| 若羌县| 衡阳县| 赤城县| 黎川县|