Java線程并發常用工具類使用

這次整理了一些比較常用的線程工具類啦。

CountDownLatch:在一組線程執行完后,才能開始執行調用等待的線程。上片文章提到過junit的測試盡量不要測試線程,如果硬是要可以使用CountDownLatch進行測試

CyclicBarrier:在一組線程中調用等待方法后,只有這組所有線程都進入等待后,會執行一個指定的線程,在指定的線程執行完后,這組等待的線程才能繼續執行。

Semaphore:可用于限流使用。

Exchanger:當兩組線程都執行到交換的方法時,能將數據在這兩個線程之間進行數據交換。

CountDownLatch

該類實現主要是由一個內部類Sync實現的,Sync繼承了AbstractQueuedSynchronizer(就是經常提到的AQS),

常用的方法有兩個:

1.await():線程調用該方法進入帶阻塞狀態,只有當調用countDown()并驟減到0的時候,才能繼續執行

2.countDown():線程驟減一個單位。

具體實現:

?

public class CountDownLatchMain {static CountDownLatch latch = new CountDownLatch(6);static class InitThread implements Runnable{public void run() {try {TimeUnit.MILLISECONDS.sleep(200L);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println("Thread name:"+Thread.currentThread().getName()+" init ...");latch.countDown();}}static class BusinessThread implements Runnable{public void run() {try {latch.await();} catch (InterruptedException e1) {e1.printStackTrace();}for(int i=0;i<3;i++) {try {TimeUnit.MILLISECONDS.sleep(100L);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Thread name : " + Thread.currentThread().getName()+" work_" + i);}}}public static void main(String[] args) throws InterruptedException {new Thread(new Runnable() {public void run() {latch.countDown();System.out.println("thread name "+Thread.currentThread().getName()+" 1st init ...");try {TimeUnit.MILLISECONDS.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}latch.countDown();System.out.println("thread name "+Thread.currentThread().getName()+" 2nd init ...");}},"Thread-0").start();new Thread(new BusinessThread()).start();for(int i=0;i<=4 ;i++) {new Thread(new InitThread()).start();}latch.await();TimeUnit.MILLISECONDS.sleep(300);System.out.println("main end ...");}
}

?執行結果:

thread name Thread-0 1st init ...
Thread name:Thread-1 init ...
Thread name:Thread-3 init ...
Thread name:Thread-2 init ...
Thread name:Thread-5 init ...
Thread name:Thread-4 init ...
Thread name : Thread-0 work_0
Thread name : Thread-0 work_1
Thread name : Thread-0 work_2
main end ...
thread name Thread-0 2nd init ...

CyclicBarrier

?

與CountDownLatch差不多,都是等待線程執行完后,才能繼續執行,不過這兩個不同的地方就是:CountDownLatch需要手動在邏輯代碼中進行驟減,減到臨界點后,阻塞的線程會繼續執行,而CountDownLatch是一組線程都進入到阻塞狀態后,然后執行指定線程執行完后,那組阻塞的線程才能繼續執行。 示例:

public class CyclicBarrierMain {static CyclicBarrier barrier = new CyclicBarrier(5,new Runnable() {public void run() {System.out.println("Thread name : " + Thread.currentThread().getName() + " barrier start...");try {TimeUnit.MILLISECONDS.sleep(100L);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println("Thread name : " + Thread.currentThread().getName() + " barrier thread ...");}});static class SubThread implements Runnable{public void run() {long sleep = (long) (Math.random()*1000);System.out.println("thread name : " + Thread.currentThread().getName() + " init ...");try {TimeUnit.MILLISECONDS.sleep(sleep);} catch (InterruptedException e) {e.printStackTrace();}try {System.out.println("thread name : " + Thread.currentThread().getName() + " sleep time:"+sleep);barrier.await();} catch (InterruptedException e) {e.printStackTrace();} catch (BrokenBarrierException e) {e.printStackTrace();}System.out.println("thread name : " + Thread.currentThread().getName() + " end ....");}}public static void main(String[] args) {for(int i =0 ; i<5;i++) {new Thread(new SubThread()).start();}}
}

執行結果:

thread name : Thread-2 init ...
thread name : Thread-4 init ...
thread name : Thread-1 init ...
thread name : Thread-0 init ...
thread name : Thread-3 init ...
thread name : Thread-2 sleep time:405
thread name : Thread-0 sleep time:488
thread name : Thread-1 sleep time:564
thread name : Thread-4 sleep time:777
thread name : Thread-3 sleep time:860
Thread name : Thread-3 barrier start...
Thread name : Thread-3 barrier thread ...
thread name : Thread-3 end ....
thread name : Thread-2 end ....
thread name : Thread-1 end ....
thread name : Thread-0 end ....
thread name : Thread-4 end ....

Semaphore

?

主要用于需要做限制的場景,比如限制連接池獲取次數等等,也有一個Sync內部類繼承了AQS

常用方法:

1、acquire():驟減一個單位,也可調用帶參的方法可指定減值,當驟減到0的時候,調用該方法會進入阻塞狀態。

2、release():釋放一個單位,也會在初始化的數量進行增加。

3、availablePermits():得到可獲取單位的數量。

4、getQueueLength():調用了acquire()方法并進入到阻塞狀態的總數量。

具體用法:

Semaphore semaphore = new Semaphore(5);
semaphore.acquire();//也可指定減少多個semaphore.acquire(2);
//...第6個acquire()方法時,再次調用將進入等待,直到在某個線程中執行了semaphore.release()方法才會繼續執行后面的
//...

Exchanger

主要用于兩個線程之間的數據交換,個人覺得這個用處不大,既然看到了這個,也就順便整理了一下

使用示例:

public class UseExcahnger {static Exchanger<Set<String>> exchanger = new Exchanger<Set<String>>();static class ThreadOne extends Thread{@Overridepublic void run() {Set<String> set = new HashSet<String>();set.add("1");set.add("2");try {System.out.println(Thread.currentThread().getName() + " > set:" + set);Thread.sleep(2000L);Set<String> exchange = exchanger.exchange(set);System.out.println(Thread.currentThread().getName() + " > " + exchange);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}static class ThreadTwo extends Thread{@Overridepublic void run() {Set<String> set = new HashSet<String>();set.add("3");set.add("4");try {System.out.println(Thread.currentThread().getName() + " > set:" + set);Thread.sleep(3000L);Set<String> exchange = exchanger.exchange(set);System.out.println(Thread.currentThread().getName() + " > " + exchange);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}public static void main(String[] args) {new ThreadOne().start();new ThreadTwo().start();}
}

執行結果為:

Thread-0 > set:[1, 2]
Thread-1 > set:[3, 4]
Thread-1 > [1, 2]
Thread-0 > [3, 4]

Future/FutureTask

這個在之前的提到過,與Callable一起使用,用來做回調的,個人覺得這個與之前的Fork/Join的分而治之有些相似,都是異步同時執行完后將結果返回,然后發現相似之后,回去看了一下源代碼

RecursiveActionRecursiveTask<T>?都分別繼承了Future接口,而FutureTask也繼承了Future、Runnable,所以FutureTask既能作為Callable帶有返回結果,也能作為Thread去執行它。

這里就介紹一下類中的一些方法,示例的話可以翻看之前的文章

1、isDone():判斷線程是否已結束。

2、boolean cancel(boolean mayInterruptIfRunning):參數為true是中斷線程,但是只會發送中斷信號,在程序中需要自行判斷,參數為false則不會中斷,返回值為true,如果線程已結束或未開始則返回false。

3、isCancelled():判斷線程是否關閉。

4、get():獲取線程返回值。

好啦,就先整理這些啦,后面還有一些還在整理,后期會繼續分享的呀,如果有問題煩請各路大佬指出

?

?

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/537181.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/537181.shtml
英文地址,請注明出處:http://en.pswp.cn/news/537181.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

三維圖形幾何變換算法實驗_計算機視覺方向簡介 | 深度學習視覺三維重建

點擊上方“計算機視覺life”&#xff0c;選擇“星標”快速獲得最新干貨作者&#xff1a; Moonsmilehttps://zhuanlan.zhihu.com/p/79628068本文已由作者授權&#xff0c;未經允許&#xff0c;不得二次轉載三維重建意義三維重建作為環境感知的關鍵技術之一&#xff0c;可用于自動…

讀《高效程序員的45個習慣——敏捷開發修煉之道》

本書主要用平易的語言講述了45個有助于提高程序員自身敏捷的習慣&#xff0c;個人感覺這種老外寫的書翻譯成中文就少了很多意思。 主要的45個習慣是&#xff1a; 做事欲速則不達對事不對人排除萬難跟蹤變化對團隊投資懂得丟棄打破沙鍋問到底把握開發節奏讓客戶做決定讓設計指導…

Java線程CAS原子操作

這次分享一些關于原子操作(CAS)的東西. 定義 CAS(Compare And Swap)是CPU的一個指令級別的操作&#xff0c;叫原子操作&#xff0c;原子操作是不可分割的&#xff0c;跟事務差不多&#xff0c;要么全部執行完成&#xff0c;要么不執行&#xff1b; 像這種操作有點類似阻塞鎖…

python 導航欄_解析導航欄的url--selnium,beautifulsoup實戰

前段時間做ui自動化測試的時候&#xff0c;導航欄菜單始終有點問題&#xff0c;最后只好直接獲取到url&#xff0c;然后直接使用driver.get(url)進入頁面&#xff1b;包括做壓測的時候&#xff0c;比如我要找出所有報表菜單的url&#xff0c;這樣不可能手動去一個一個找出來&am…

PNG圖片詳解

1、PNG圖片類型 PNG格式有8位、24位、32位三種&#xff0c;下面是一些術語&#xff1a; 索引透明&#xff1a;類似于GIF&#xff0c;某一像素只有全透和全不透明兩種效果Alpha透明&#xff1a;半透明PNG8 8位的PNG最多支持256&#xff08;2的8次方&#xff09;種顏色&#xff0…

Java并發編程之顯式鎖(Lock)使用

又是一個基于AQS好用的類&#xff0c;看來下次有必要看看AQS了&#xff0c;正好又是放假。 既然叫顯式鎖&#xff0c;必然也有隱式鎖&#xff0c;也就是所謂的synchronzied關鍵字&#xff0c;它們兩者的區別呢在于使用范圍&#xff0c;synchronzied關鍵字的使用范圍比Lock要小…

python pychart三維_詳解python模塊pychartdir安裝及導入問題

在遷移別人寫好的腳本時&#xff0c;發現pychartdir沒有導入&#xff0c;腳本執行報錯。以下是報錯內容&#xff1a;[modpsLGJF-ZYC5-MMSC-WEB02 ~]$ python /opt/aspire/product/modps/mopps/shell/dayreport_linux.py/etc/host.conf: line 1: bad command nospoof on"Tr…

vim 中Ctags的安裝和使用

Ctags是一個用來為源文件中的標識符&#xff08;如變量、函數、類成員、宏定義等&#xff09;創建索引文件的程序。這些tags文件能被編輯器或其它工具用來快速查找定位源代碼中的符號&#xff08;tag/symbol&#xff09;&#xff0c;如變量名&#xff0c;函數名等。 Tags文件中…

Java并發編程之AbstractQueuedSynchronizer(AQS)源碼解析

自己一個人隨便看看源碼學習的心得&#xff0c;分享一下啦&#xff0c;不過我覺得還是建議去買本Java并發編程的書來看會比較好點&#xff0c;畢竟個人的理解有限嘛。 獨占鎖和共享鎖 首先先引入這兩個鎖的概念&#xff1a;獨占鎖即同一時刻只有一個線程才能獲取到鎖&#xf…

采集用python還是火車頭_我才知道爬蟲也可以醬紫--火車采集器

我才知道爬蟲還可以這樣—火車采集器的使用說在前面額。。。好吧&#xff0c;我這一個三毛錢的屌絲也開始步入實習階段了&#xff0c;在北京其實也挺好的&#xff0c;雖說壓力大&#xff0c;但是今后就業機會也相對而言大一些。好了&#xff0c;說回今天的主題&#xff0c;之前…

mvn 使用中的錯誤

出現這種錯誤的時候&#xff1a;mvn Error building POM may not be this projects POM&#xff0c;報的是那個jar 包&#xff0c;就刪除那個jar 包&#xff0c;重新mvn clean install .ok

Java并發編程之FutureTask源碼解析

上次總結一下AQS的一些相關知識&#xff0c;這次總結了一下FutureTask的東西&#xff0c;相對于AQS來說簡單好多呀 之前提到過一個LockSupport的工具類&#xff0c;也了解一下這個工具類的用法&#xff0c;這里也鞏固一下吧 /*** Makes available the permit for the given th…

java 刪除二維數組中的null_避免在Java中檢查Null語句

1.概述通常&#xff0c;在Java代碼中處理null變量、引用和集合很棘手。它們不僅難以識別&#xff0c;而且處理起來也很復雜。事實上&#xff0c;在編譯時無法識別處理null的任何錯誤&#xff0c;會導致運行時NullPointerException。在本教程中&#xff0c;我們將了解在Java中檢…

Java并發編程之并發容器ConcurrentHashMap(JDK1.7)解析

最近看了一下ConcurrentHashMap的相關代碼&#xff0c;感覺JDK1.7和JDK1.8差別挺大的&#xff0c;這次先看下JDK1.7是怎么實現的吧 哈希&#xff08;hash&#xff09; 先了解一下啥是哈希&#xff08;網上有很多介紹&#xff09;&#xff0c;是一種散列函數&#xff0c;簡單來…

帶控制端的邏輯運算電路_分別完成正整數的平方、立方和階乘的運算verilog語言...

練習&#xff1a;設計一個帶控制端的邏輯運算電路&#xff0c;分別完成正整數的平方、立方和階乘的運算。 //--------------myfunction---------- modulemyfunction(clk,n,result,reset,sl); output[6:0]result; input[2:0] n; input reset,clk; input [1:0] sl; reg[6:0]resul…

Java并發編程之并發容器ConcurrentHashMap(JDK1.8)解析

這個版本ConcurrentHashMap難度提升了很多&#xff0c;就簡單的談一下常用的方法就好了&#xff0c;可能有些講的不太清楚&#xff0c;麻煩發現的大佬指正一下 主要數據結構 1.8將Segment取消了&#xff0c;保留了table數組的形式&#xff0c;但是不在以HashEntry純鏈表的形式…

simulink顯示多個數據_如何在 Simulink 中使用 PID Tuner 進行 PID 調參?

作者 | 安布奇責編 | 胡雪蕊出品 | CSDN(ID: CSDNnews)本文為一篇技術干貨&#xff0c;主要講述在Simulink如何使用PID Tuner進行PID調參。PID調參器( PIDTuner)概述1.1 簡介使用PID Tuner可以對Simulink模型中的PID控制器&#xff0c;離散PID控制器&#xff0c;兩自由度PID控制…

Java并發編程之堵塞隊列介紹以及SkipList(跳表)

堵塞隊列 先了解一下生產者消費者模式&#xff1a; 生產者就是生產數據的一方&#xff0c;消費者就是消費數據的另一方。在多線程開發中&#xff0c;如果生產者處理速度很快&#xff0c;而消費者處理速度很慢&#xff0c;那么生產者就必須等待消費者處理完&#xff0c;才能繼…

python生成list的時候 可以用lamda也可以不用_python 可迭代對象,迭代器和生成器,lambda表達式...

分頁查找#5.隨意寫一個20行以上的文件(divmod)# 運行程序&#xff0c;先將內容讀到內存中&#xff0c;用列表存儲。# l []# 提示&#xff1a;一共有多少頁# 接收用戶輸入頁碼&#xff0c;每頁5條&#xff0c;僅輸出當頁的內容def read_page(bk_list,n,endlineNone):startline …

數據挖掘技術簡介[轉]

關鍵詞&#xff1a; 關鍵詞&#xff1a;數據挖掘 數據集合 1. 引言  數據挖掘(Data Mining)是從大量的、不完全的、有噪聲的、模糊的、隨機的數據中提取隱含在其中的、人們事先不知道的、但又是潛在有用的信息和知識的過程。隨…