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

Java中JUC包(java.util.concurrent)下的常用子類

 更新時(shí)間:2022年12月20日 14:11:53   作者:Killing?Vibe  
相信大家已經(jīng)對(duì)并發(fā)機(jī)制中出現(xiàn)的很多的常見知識(shí)點(diǎn)進(jìn)行了總結(jié),下面這篇文章主要給大家介紹了關(guān)于Java中JUC包(java.util.concurrent)下的常用子類的相關(guān)資料,文中通過圖文以及示例代碼介紹的非常詳細(xì),需要的朋友可以參考下

一、對(duì)象鎖juc.locks包

在Java中除了synchronized關(guān)鍵字可以實(shí)現(xiàn)對(duì)象鎖之外,java.util.concurrent中的Lock接口也可以實(shí)現(xiàn)對(duì)象鎖。

介紹一下這個(gè)lock鎖的簡(jiǎn)要實(shí)現(xiàn):

  • JDK1.0就有的,需要JVM借助操作系統(tǒng)提供的mutex系統(tǒng)原語實(shí)現(xiàn)
  • JDK1.5之后,Java語言自己實(shí)現(xiàn)的互斥鎖實(shí)現(xiàn),不需要借助操作系統(tǒng)的monitor機(jī)制。

注:使用Lock接口需要顯式的進(jìn)行加鎖和解鎖操作。

我們可以使用Lock接口的實(shí)現(xiàn)子類ReentrantLock來進(jìn)行加鎖解鎖:

ReentrantLock 可重入互斥鎖. 和 synchronized 定位類似, 都是用來實(shí)現(xiàn)互斥效果, 保證線程安全.

ReentrantLock 的用法:

  • lock()加鎖,獲取鎖失敗的線程進(jìn)入阻塞狀態(tài),直到其他線程釋放鎖,再次競(jìng)爭(zhēng),死等。
  • trylock(超時(shí)時(shí)間): 加鎖, 獲取鎖失敗的線程進(jìn)入阻塞態(tài),等待一段時(shí)間,時(shí)間過了若還未獲取到鎖恢復(fù)執(zhí)行,放棄加鎖,執(zhí)行其他代碼
  • unlock()解鎖

synchronized和lock的區(qū)別:

synchronized 是Java的關(guān)鍵字, 由 JVM 實(shí)現(xiàn),需要依賴操作系統(tǒng)提供的線程互斥原語(mutex),而Lock標(biāo)準(zhǔn)庫的類和接口,其中一個(gè)最常用的子類( ReentrantLock ,可重入鎖),由Java本身實(shí)現(xiàn)的,不需要依賴操作系統(tǒng)。

synchronized 隱式的加鎖和解鎖,lock需要顯示進(jìn)行加鎖和解鎖

synchronized 在獲取鎖失敗的線程時(shí),死等;lock可以使用trylock等待一段時(shí)間之后自動(dòng)放棄加鎖,線程恢復(fù)執(zhí)行

synchronized 是非公平鎖, ReentrantLock 默認(rèn)是非公平鎖. 可以通過構(gòu)造方法傳入一個(gè) true 開啟公平鎖模式.

synchronized不支持讀寫鎖,Lock子類ReentrantReadWriteLock支持讀寫鎖。

更強(qiáng)大的喚醒機(jī)制. synchronized 是通過 Object 的 wait / notify 實(shí)現(xiàn)等待-喚醒. 每次喚醒的是一個(gè)隨機(jī)等待的線程.ReentrantLock搭配 Condition 類實(shí)現(xiàn)等待-喚醒, 可以更精確控制喚醒某個(gè)指定的線程

小結(jié):

一般場(chǎng)景synchronized足夠用了,需要用超時(shí)等待鎖,公平鎖,讀寫鎖再考慮使用juc.lock

如何選擇使用哪個(gè)鎖?

  • 鎖競(jìng)爭(zhēng)不激烈的時(shí)候, 使用 synchronized, 效率更高, 自動(dòng)釋放更方便.
  • 鎖競(jìng)爭(zhēng)激烈的時(shí)候, 使用 ReentrantLock, 搭配 trylock 更靈活控制加鎖的行為, 而不是死等.
  • 如果需要使用公平鎖, 使用 ReentrantLock.

二、原子類

原子類內(nèi)部用的是 CAS 實(shí)現(xiàn),所以性能要比加鎖實(shí)現(xiàn) i++ 高很多。原子類有以下幾個(gè):

  • AtomicBoolean
  • AtomicInteger
  • AtomicIntegerArray
  • AtomicLong
  • AtomicReference
  • AtomicStampedReference

以 AtomicInteger 舉例,常見方法有:

addAndGet(int delta);   i += delta;
decrementAndGet(); --i;
getAndDecrement(); i--;
incrementAndGet(); ++i;
getAndIncrement(); i++;

三、四個(gè)常用工具類

juc包下一共有四個(gè)常用工具類:

  • 信號(hào)量 - Semaphore
  • 計(jì)數(shù)器 - CountDownLatch
  • 循環(huán)柵欄 - CyclicBarrier
  • 兩個(gè)線程之間的交換器 - Exchanger

3.1 信號(hào)量 Semaphore

信號(hào)量Semaphore就是一個(gè)計(jì)數(shù)器,表示當(dāng)前可用資源的個(gè)數(shù)

關(guān)于信號(hào)量Semaphore有兩個(gè)核心操作:

  • P - 申請(qǐng)資源操作
  • V - 釋放資源操作

Semaphore 的PV加減操作都是原子性的,再多線程場(chǎng)景下可以直接使用

public static void main(String[] args) {
        // 在構(gòu)造參數(shù)傳入可用資源的個(gè)數(shù)
        // 可用資源為6個(gè)
        Semaphore semaphore = new Semaphore(6);
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println(Thread.currentThread().getName() + "準(zhǔn)備申請(qǐng)資源");
                    // P操作,每次申請(qǐng)兩個(gè)資源
                    semaphore.acquire(2);
                    System.out.println(Thread.currentThread().getName() + "獲取資源成功");
                    Thread.sleep(1000);
                    System.out.println(Thread.currentThread().getName() + "釋放資源");
                    // V操作,默認(rèn)釋放一個(gè)占有的資源
                    semaphore.release(2);
                }catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        for (int i = 0; i < 20; i++) {
            Thread t = new Thread(runnable,String.valueOf(i + 1));
            t.start();
        }
    }

3.2 CountDownLatch

有點(diǎn)類似于大號(hào)的join方法

調(diào)用await方法的線程需要等待其他線程將計(jì)數(shù)器減為0才能繼續(xù)恢復(fù)執(zhí)行。

public static void main(String[] args) throws InterruptedException {
        // 等待線程需要等待的線程數(shù),必須等這10個(gè)子線程全部執(zhí)行完畢再恢復(fù)執(zhí)行
        CountDownLatch latch = new CountDownLatch(10);
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(new Random().nextInt(1000));
                    System.out.println(Thread.currentThread().getName() + "到達(dá)終點(diǎn)");
                    // 計(jì)數(shù)器 - 1
                    latch.countDown();
                }catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        for (int i = 0; i < 10; i++) {
            Thread t = new Thread(runnable,"運(yùn)動(dòng)員" + i + 1);
            t.start();
        }
        // main線程就是裁判線程,需要等待所有運(yùn)動(dòng)員到底終點(diǎn)再恢復(fù)執(zhí)行
        // 直到所有線程調(diào)用countdown方法將計(jì)數(shù)器減為0繼續(xù)執(zhí)行
        latch.await();
        System.out.println("比賽結(jié)束~最終獲勝的是鵬哥,有請(qǐng)冠軍給大家高歌一首~");
    }

總結(jié)

至于CyclicBarrier和Exchanger在本篇就不多介紹,讀者可以自行查閱一下官方文檔進(jìn)行仔細(xì)的學(xué)習(xí)~如果有問題可以私信博主,別忘了點(diǎn)贊收藏+關(guān)注哦!

相關(guān)文章

  • Java的封裝類和裝箱拆箱詳解

    Java的封裝類和裝箱拆箱詳解

    Java中存在基礎(chǔ)數(shù)據(jù)類型,但是在某些情況下,我們要對(duì)基礎(chǔ)數(shù)據(jù)類型進(jìn)行對(duì)象的操作,例如,集合中只能存對(duì)象,而不能存在基礎(chǔ)數(shù)據(jù)類型,于是便出現(xiàn)了封裝類,本文將詳細(xì)給大家介紹Java封裝類和裝箱拆箱,需要的朋友可以參考下
    2023-05-05
  • java中如何使用泛型方法比較大小

    java中如何使用泛型方法比較大小

    這篇文章主要介紹了java中如何使用泛型方法比較大小,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • Oracle + Mybatis實(shí)現(xiàn)批量插入、更新和刪除示例代碼

    Oracle + Mybatis實(shí)現(xiàn)批量插入、更新和刪除示例代碼

    利用MyBatis動(dòng)態(tài)SQL的特性,我們可以做一些批量的操作,下面這篇文章主要給大家介紹了關(guān)于Oracle + Mybatis實(shí)現(xiàn)批量插入、更新和刪除的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧。
    2018-01-01
  • Java+OpenCV實(shí)現(xiàn)人臉檢測(cè)并自動(dòng)拍照

    Java+OpenCV實(shí)現(xiàn)人臉檢測(cè)并自動(dòng)拍照

    這篇文章主要為大家詳細(xì)介紹了Java+OpenCV實(shí)現(xiàn)人臉檢測(cè),并調(diào)用筆記本攝像頭實(shí)時(shí)抓拍,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • Java實(shí)現(xiàn) 基于密度的局部離群點(diǎn)檢測(cè)------lof算法

    Java實(shí)現(xiàn) 基于密度的局部離群點(diǎn)檢測(cè)------lof算法

    這篇文章主要介紹了Java實(shí)現(xiàn) 基于密度的局部離群點(diǎn)檢測(cè)------lof算法,本文通過算法概述,算法Java源碼,測(cè)試結(jié)果等方面一一進(jìn)行說明,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • 詳解Java 對(duì)象序列化和反序列化

    詳解Java 對(duì)象序列化和反序列化

    本篇文章主要介紹了Java 對(duì)象序列化和反序列化,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-03-03
  • Java HashMap三種循環(huán)遍歷方式及其性能對(duì)比實(shí)例分析

    Java HashMap三種循環(huán)遍歷方式及其性能對(duì)比實(shí)例分析

    這篇文章主要介紹了Java HashMap三種循環(huán)遍歷方式及其性能對(duì)比,結(jié)合具體實(shí)例形式分析了Java HashMap三種循環(huán)遍歷方式的實(shí)現(xiàn)方法、運(yùn)行效率及性能優(yōu)劣,需要的朋友可以參考下
    2019-10-10
  • java求最大公約數(shù)與最小公倍數(shù)的方法示例

    java求最大公約數(shù)與最小公倍數(shù)的方法示例

    這篇文章主要介紹了java求最大公約數(shù)與最小公倍數(shù)的方法,涉及java數(shù)值運(yùn)算的相關(guān)操作技巧,并附帶分析了eclipse環(huán)境下設(shè)置運(yùn)行輸入?yún)?shù)的相關(guān)操作技巧,需要的朋友可以參考下
    2017-11-11
  • springboot2中使用@JsonFormat注解不生效的解決

    springboot2中使用@JsonFormat注解不生效的解決

    這篇文章主要介紹了springboot2中使用@JsonFormat注解不生效的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • Java 字符串反轉(zhuǎn)實(shí)現(xiàn)代碼

    Java 字符串反轉(zhuǎn)實(shí)現(xiàn)代碼

    這篇文章主要介紹了 Java 字符串反轉(zhuǎn)實(shí)現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下
    2017-03-03

最新評(píng)論