2023-07-03 09:09:49來源:Java技術(shù)指北
JUC(java.util.concurrent)是在Java 5中引入的一個并發(fā)編程的擴展庫,目的是為了更加方便、快捷和安全地實現(xiàn)并發(fā)編程。它提供了一系列的工具類、鎖、隊列以及原子類等來協(xié)調(diào)多線程之間的操作。
基于現(xiàn)代硬件不斷地發(fā)展,為了充分利用服務(wù)器資源,并發(fā)編程在我們的開發(fā)中已經(jīng)無處不在,今天主要了解下JUC包中提供的幾個工具類,讓我們在并發(fā)編程時提供助力。
(資料圖片僅供參考)
Java并發(fā)編程是一門復(fù)雜的技術(shù),其中有一些難點需要特別注意。以下是一些Java并發(fā)編程的難點:
線程安全:多線程執(zhí)行的代碼必須是線程安全的,否則會產(chǎn)生競態(tài)條件和其他問題。死鎖:當(dāng)多個線程因為互相等待其他線程釋放鎖而無法繼續(xù)執(zhí)行時,就會產(chǎn)生死鎖。競態(tài)條件:當(dāng)多個線程試圖同時訪問同一個共享資源時,就會產(chǎn)生競態(tài)條件。內(nèi)存可見性:多個線程同時訪問同一個變量時,可能會產(chǎn)生內(nèi)存可見性問題,即一個線程對變量的修改不會立即被其他線程所感知。并發(fā)集合類:Java提供了一些并發(fā)集合類,如ConcurrentHashMap和ConcurrentLinkedQueue,但使用它們需要注意一些細(xì)節(jié)問題。線程池:線程池是Java并發(fā)編程中的一個重要概念,但線程池的使用也需要注意一些問題,如線程池大小、任務(wù)隊列類型等。CAS操作:Java提供了CAS(Compare-And-Swap)操作,可以用于實現(xiàn)非阻塞算法,但使用CAS操作需要非常小心,以免產(chǎn)生ABA問題等。工具類CountDownLatchCountDownLatch是一個同步輔助類,使用一個給定數(shù)量的計數(shù)器,當(dāng)該計數(shù)器不為0時,將程序阻塞在wait()處,當(dāng)線程執(zhí)行完成后通過調(diào)用countDown()使計數(shù)器減一, 直到計數(shù)器為0后才會繼續(xù)執(zhí)行后續(xù)代碼。主要實現(xiàn)某個任務(wù)依賴其他一個或多個異步任務(wù)的執(zhí)行結(jié)果的場景核心方法:
/** * 定義計數(shù)器數(shù)量,用于定義多少個執(zhí)行線程 */public CountDownLatch(int count);/** * 阻塞方法,直到計數(shù)器為0時才會繼續(xù)執(zhí)行后續(xù)代碼 */public void await();/** * 每次調(diào)用改方法,則計數(shù)器減一 */public void countDown();
CyclicBarrierCyclicBarrier內(nèi)部同樣定義了計數(shù)器,只不過每當(dāng)有線程執(zhí)行完后改計數(shù)器加一,直至達(dá)到定義數(shù)量后,執(zhí)行定義的回調(diào)函數(shù)與await()后續(xù)代碼。 與CountDownLatch相比,CyclicBarrier會對子任務(wù)阻塞,而CountDownLatch則阻塞主任務(wù);另外CyclicBarrier可以重復(fù)使用。主要實現(xiàn)某個回調(diào)函數(shù)在一個或多個線程執(zhí)行完成后觸發(fā)的情形核心方法:
/** * 定義計數(shù)器數(shù)量與回調(diào)函數(shù) */public CyclicBarrier(int parties, Runnable barrierAction);/** * 阻塞方法,當(dāng)有線程執(zhí)行到則計數(shù)器加一,等到達(dá)到目標(biāo)數(shù)后才會繼續(xù)后續(xù)代碼 */public int await();/** * 通過該方法可以實現(xiàn)計數(shù)器的重置 */public void reset();
Semaphore信號量通常用于限制可以訪問某些(物理或邏輯)資源的線程數(shù)。適用于有限資源數(shù)量的控制核心方法:
/** * 定義許可數(shù)量 */public Semaphore(int permits);/** * 申請許可,改方法會阻塞程序 */public void acquire();/** * 釋放許可 */public void release();
示例CountDownLatch的使用場景
CountDownLatch是Java并發(fā)包中的一個工具類,它可以實現(xiàn)線程之間的協(xié)作。具體來說,CountDownLatch可以讓一個線程等待多個線程執(zhí)行完畢,再繼續(xù)執(zhí)行。CountDownLatch常用于以下場景:
主線程等待多個子線程執(zhí)行完畢。多個子線程等待某個共同任務(wù)的完成。模擬并發(fā)請求,等待所有請求都響應(yīng)完畢再進(jìn)行下一步操作。統(tǒng)計多個線程執(zhí)行的時間。@Test public void test() throws InterruptedException { int count = 10; CountDownLatch countDownLatch = new CountDownLatch(count); IntStream.range(0,count).forEach(i->{ new Thread(()->{ System.out.println( "執(zhí)行線程:"+ i ); try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { throw new RuntimeException(e); } countDownLatch.countDown(); }).start(); }); countDownLatch.await(); System.out.println("線程執(zhí)行完成"); }
CyclicBarrier的使用場景
它允許多個線程在某個屏障處等待,直到所有線程都到達(dá)該屏障時才會繼續(xù)執(zhí)行。
CyclicBarrier 適用于一組線程需要相互等待,直到所有線程都完成某個任務(wù)后才能繼續(xù)執(zhí)行下一步操作的場景。例如,一個大型的計算任務(wù)可以被分成多個子任務(wù), 每個子任務(wù)由一個線程執(zhí)行。當(dāng)所有子任務(wù)完成后,這些線程需要等待,直到所有子任務(wù)都完成,然后再執(zhí)行下一步操作。
另外,CyclicBarrier 還可以用于優(yōu)化代碼性能。例如,當(dāng)我們需要等待多個線程都完成某項工作后,才能進(jìn)行下一步操作。此時,我們可以使用 CyclicBarrier 來實現(xiàn)等待, 而不是使用 Thread.sleep() 方法等待一段時間。這樣可以避免無謂的等待時間,提高代碼效率。
@Test public void test() { int count = 10; AtomicBoolean finish = new AtomicBoolean(false); CyclicBarrier cyclicBarrier = new CyclicBarrier(count, ()->{ System.out.println("線程執(zhí)行完成"); finish.set(true); }); IntStream.range(0,count).forEach(i->{ new Thread(()->{ System.out.println( "執(zhí)行線程:"+ i ); try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { throw new RuntimeException(e); } try { cyclicBarrier.await(); } catch (InterruptedException e) { throw new RuntimeException(e); } catch (BrokenBarrierException e) { throw new RuntimeException(e); } }).start(); }); while (!finish.get()){} }
Semaphore的使用場景
它可以控制同時訪問某個共享資源的線程數(shù)量。常用于限制同時訪問某個資源的線程數(shù)量,例如數(shù)據(jù)庫連接池、線程池等。
控制并發(fā)線程數(shù):Semaphore可以限制并發(fā)線程數(shù),從而控制系統(tǒng)資源的使用情況??刂圃L問資源數(shù):Semaphore可以控制同時訪問某個資源的線程數(shù)量,例如數(shù)據(jù)庫連接池,限制連接數(shù)。實現(xiàn)生產(chǎn)者-消費者模型:Semaphore可以與阻塞隊列一起使用,實現(xiàn)生產(chǎn)者-消費者模型,控制生產(chǎn)者和消費者的數(shù)量。多個線程間的協(xié)作:Semaphore可以用于多個線程之間的協(xié)作,例如某個線程需要等待某些條件滿足后才能繼續(xù)執(zhí)行,可以使用Semaphore來實現(xiàn)等待和喚醒操作。@Test public void test() { int count = 10; Semaphore semaphore = new Semaphore(3); IntStream.range(0,count).forEach(i->{ new Thread(()->{ try { semaphore.acquire(); } catch (InterruptedException e) { throw new RuntimeException(e); } System.out.println( "執(zhí)行線程:"+ i ); try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { throw new RuntimeException(e); } semaphore.release(); }).start(); }); while (true){} }
結(jié)束語涉及到線程的開發(fā)都伴隨著復(fù)雜性,不管是在代碼調(diào)試上還是理解線程切換與安全性上,JUC提供的各種強大的工具類將并發(fā)編程的復(fù)雜性進(jìn)行了封裝,不管是在使用或是擴展上,都能通過簡單的幾行代碼實現(xiàn)多線程的各種協(xié)調(diào)工作。
關(guān)鍵詞:
JUC-輔助類JUC(java util concurrent)是在Java5中引入的一個并發(fā)編程
為什么要多階段構(gòu)建大家都知道Golang是編譯型語言,源碼需要先編譯再運
一、類和對象1、什么是類和對象面向?qū)ο缶幊淌且环N編程范式,它將程序
之前在這篇文章(CSS實現(xiàn)樹狀結(jié)構(gòu)目錄[1])中實現(xiàn)了一個樹狀結(jié)構(gòu),效果
需求集中釋放后,市場掉頭向下。
家長在為孩子選擇國際學(xué)校綜合考慮的因素很多,比如學(xué)費、課程體系、師
陵川補齊農(nóng)村黨建“短板”助推鄉(xiāng)村振興,主流媒體,山西門戶。山西新聞網(wǎng)
7月3日,信音電子(301329 SZ)開啟申購,發(fā)行價格為21 00元 股,申購上
新華社羅馬7月2日電(國際觀察)全球糧農(nóng)事業(yè)發(fā)展的中國貢獻(xiàn)新華社記者
火箭在幾天前還在追求天賦,在幾天后立刻放棄了天賦?,老鷹,天賦,火箭
1、手上起小紅疙瘩很癢,有以下幾種可能:1??赡苁墙戬?,主要由疥瘡感
證券時報網(wǎng)訊,7月2日,永泰能源(600157)發(fā)布公告,公司核心管理人員將
本周觀點:本周酒鬼酒、古井貢酒、瀘州老窖召開2022年度股東大會,整體
證券時報e公司訊,近日,萬興科技(300624)旗下億圖腦圖正式上線AI繪畫
1、北京花鮮素國際貿(mào)易有限公司成立于2014年,公司致力于鮮花提純飲品