CountDownLatch和CyclicBarrier模擬同時(shí)并發(fā)請(qǐng)求

  有時(shí)候要測(cè)試一下某個(gè)功能的并發(fā)能力,又不要想借助于其他測(cè)試工具瓮下,索性就自己寫(xiě)簡(jiǎn)單的demo模擬一個(gè)并發(fā)請(qǐng)求就最方便了。如果熟悉jemter的測(cè)試某接口的并發(fā)能力其實(shí)更專業(yè),此處只是自己折騰著玩。

CountDownLatch和CyclicBarrier是jdk concurrent包下非常有用的兩個(gè)并發(fā)工具類荠商,它們提供了一種控制并發(fā)流程的手段皆撩。其實(shí)查看源碼它們都是在內(nèi)部維護(hù)了一個(gè)計(jì)數(shù)器控制流程的

CountDownLatch:一個(gè)或者多個(gè)線程溃列,等待其他多個(gè)線程完成某件事情之后才能執(zhí)行趾浅;

CyclicBarrier:多個(gè)線程互相等待胁编,直到到達(dá)同一個(gè)同步點(diǎn)酷鸦,再繼續(xù)一起執(zhí)行。

CountDownLatch和CyclicBarrier的區(qū)別

CountDownLatch的計(jì)數(shù)器滥比,線程完成一個(gè)記錄一個(gè)亚脆,計(jì)數(shù)器是遞減??計(jì)數(shù)器,只能使用一次

CyclicBarrier的計(jì)數(shù)器 更像是一個(gè)閥門(mén)盲泛,需要所有線程都到達(dá)濒持,閥門(mén)才能打開(kāi),然后繼續(xù)執(zhí)行查乒,計(jì)數(shù)器是遞增??計(jì)數(shù)器提供reset功能弥喉,可以多次使用

   另外Semaphore可以控同時(shí)訪問(wèn)的線程個(gè)數(shù),通過(guò) acquire() 獲取一個(gè)許可玛迄,如果沒(méi)有就等待由境,而 release() 釋放一個(gè)許可。


  通常我們模擬并發(fā)請(qǐng)求蓖议,一般都是多開(kāi)幾個(gè)線程虏杰,發(fā)起請(qǐng)求就好了。但是方式勒虾,一般會(huì)存在啟動(dòng)的先后順序了纺阔,算不得真正的同時(shí)并發(fā)!怎么樣才能做到真正的同時(shí)并發(fā)呢修然?是本文想說(shuō)的點(diǎn)笛钝,java中提供了閉鎖 CountDownLatch, CyclicBarrier 剛好就用來(lái)做這種事就最合適了质况。

  下面分別使用CountDownLatch和CyclicBarrier來(lái)模擬并發(fā)的請(qǐng)求

CountDownLatch模擬

package com.test; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.concurrent.CountDownLatch; public class LatchTest { public static void main(String[] args) throws InterruptedException { Runnable taskTemp = new Runnable() {        // 注意,此處是非線程安全的玻靡,留坑 private int iCounter; @Override public void run() { for(int i = 0; i < 10; i++) { // 發(fā)起請(qǐng)求 // HttpClientOp.doGet("https://www.baidu.com/"); iCounter++; System.out.println(System.nanoTime() + " [" + Thread.currentThread().getName() + "] iCounter = " + iCounter); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } }; LatchTest latchTest = new LatchTest(); latchTest.startTaskAllInOnce(5, taskTemp); } public long startTaskAllInOnce(int threadNums, final Runnable task) throws InterruptedException { final CountDownLatch startGate = new CountDownLatch(1); final CountDownLatch endGate = new CountDownLatch(threadNums); for(int i = 0; i < threadNums; i++) { Thread t = new Thread() { public void run() { try { // 使線程在此等待结榄,當(dāng)開(kāi)始門(mén)打開(kāi)時(shí),一起涌入門(mén)中 startGate.await(); try { task.run(); } finally { // 將結(jié)束門(mén)減1囤捻,減到0時(shí)臼朗,就可以開(kāi)啟結(jié)束門(mén)了 endGate.countDown(); } } catch (InterruptedException ie) { ie.printStackTrace(); } } }; t.start(); } long startTime = System.nanoTime(); System.out.println(startTime + " [" + Thread.currentThread() + "] All thread is ready, concurrent going..."); // 因開(kāi)啟門(mén)只需一個(gè)開(kāi)關(guān),所以立馬就開(kāi)啟開(kāi)始門(mén) startGate.countDown(); // 等等結(jié)束門(mén)開(kāi)啟 endGate.await(); long endTime = System.nanoTime(); System.out.println(endTime + " [" + Thread.currentThread() + "] All thread is completed."); return endTime - startTime; } }

執(zhí)行結(jié)果


CyclicBarrier模擬

// 與 閉鎖 結(jié)構(gòu)一致 public class LatchTest { public static void main(String[] args) throws InterruptedException { Runnable taskTemp = new Runnable() { private int iCounter; @Override public void run() { // 發(fā)起請(qǐng)求 // HttpClientOp.doGet("https://www.baidu.com/"); iCounter++; System.out.println(System.nanoTime() + " [" + Thread.currentThread().getName() + "] iCounter = " + iCounter); } }; LatchTest latchTest = new LatchTest(); // latchTest.startTaskAllInOnce(5, taskTemp); latchTest.startNThreadsByBarrier(5, taskTemp); } public void startNThreadsByBarrier(int threadNums, Runnable finishTask) throws InterruptedException { // 設(shè)置柵欄解除時(shí)的動(dòng)作蝎土,比如初始化某些值 CyclicBarrier barrier = new CyclicBarrier(threadNums, finishTask); // 啟動(dòng) n 個(gè)線程视哑,與柵欄閥值一致,即當(dāng)線程準(zhǔn)備數(shù)達(dá)到要求時(shí)誊涯,柵欄剛好開(kāi)啟挡毅,從而達(dá)到統(tǒng)一控制效果 for (int i = 0; i < threadNums; i++) { Thread.sleep(100); new Thread(new CounterTask(barrier)).start(); } System.out.println(Thread.currentThread().getName() + " out over..."); } } class CounterTask implements Runnable { // 傳入柵欄,一般考慮更優(yōu)雅方式 private CyclicBarrier barrier; public CounterTask(final CyclicBarrier barrier) { this.barrier = barrier; } public void run() { System.out.println(Thread.currentThread().getName() + " - " + System.currentTimeMillis() + " is ready..."); try { // 設(shè)置柵欄醋拧,使在此等待慷嗜,到達(dá)位置的線程達(dá)到要求即可開(kāi)啟大門(mén) barrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " - " + System.currentTimeMillis() + " started..."); } }

執(zhí)行結(jié)果


并發(fā)請(qǐng)求操作流程示意圖如下:


  此處設(shè)置了一道門(mén)淀弹,以保證所有線程可以同時(shí)生效丹壕。但是,此處的同時(shí)啟動(dòng)薇溃,也只是語(yǔ)言層面的東西菌赖,也并非絕對(duì)的同時(shí)并發(fā)。具體的調(diào)用還要依賴于CPU個(gè)數(shù)沐序,線程數(shù)及操作系統(tǒng)的線程調(diào)度功能等琉用,不過(guò)咱們也無(wú)需糾結(jié)于這些了,重點(diǎn)在于理解原理策幼!

  畢竟測(cè)試并發(fā) 還得用專業(yè)的工具 jmeter 還是很方便的.

在這里給大家提供一個(gè)學(xué)習(xí)交流的平臺(tái)邑时,Java技術(shù)交流┟?810309655

具有1-5工作經(jīng)驗(yàn)的,面對(duì)目前流行的技術(shù)不知從何下手特姐,需要突破技術(shù)瓶頸的可以加群晶丘。

在公司待久了,過(guò)得很安逸唐含,但跳槽時(shí)面試碰壁浅浮。需要在短時(shí)間內(nèi)進(jìn)修、跳槽拿高薪的可以加群捷枯。

如果沒(méi)有工作經(jīng)驗(yàn)滚秩,但基礎(chǔ)非常扎實(shí),對(duì)java工作機(jī)制淮捆,常用設(shè)計(jì)思想郁油,常用java開(kāi)發(fā)框架掌握熟練的可以加群本股。

________________________________________________________________________________________________

加Java架構(gòu)師進(jìn)階交流群獲取Java工程化、高性能及分布式桐腌、高性能痊末、深入淺出。高架構(gòu)哩掺。

性能調(diào)優(yōu)凿叠、Spring,MyBatis嚼吞,Netty源碼分析和大數(shù)據(jù)等多個(gè)知識(shí)點(diǎn)高級(jí)進(jìn)階干貨的直播免費(fèi)學(xué)習(xí)權(quán)限

都是大牛帶飛?讓你少走很多的彎路的?群號(hào)是:?810309655對(duì)了?小白勿進(jìn)?最好是有開(kāi)發(fā)經(jīng)驗(yàn)

注:加群要求

1盒件、具有工作經(jīng)驗(yàn)的,面對(duì)目前流行的技術(shù)不知從何下手舱禽,需要突破技術(shù)瓶頸的可以加炒刁。

2、在公司待久了誊稚,過(guò)得很安逸翔始,但跳槽時(shí)面試碰壁。需要在短時(shí)間內(nèi)進(jìn)修里伯、跳槽拿高薪的可以加城瞎。

3、如果沒(méi)有工作經(jīng)驗(yàn)疾瓮,但基礎(chǔ)非常扎實(shí)脖镀,對(duì)java工作機(jī)制,常用設(shè)計(jì)思想狼电,常用java開(kāi)發(fā)框架掌握熟練的蜒灰,可以加。

4肩碟、覺(jué)得自己很牛B强窖,一般需求都能搞定。但是所學(xué)的知識(shí)點(diǎn)沒(méi)有系統(tǒng)化削祈,很難在技術(shù)領(lǐng)域繼續(xù)突破的可以加翅溺。

5.阿里Java高級(jí)大牛直播講解知識(shí)點(diǎn),分享知識(shí)岩瘦,多年工作經(jīng)驗(yàn)的梳理和總結(jié)未巫,帶著大家全面、科學(xué)地建立自己的技術(shù)體系和技術(shù)認(rèn)知启昧!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末叙凡,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子密末,更是在濱河造成了極大的恐慌握爷,老刑警劉巖跛璧,帶你破解...
    沈念sama閱讀 212,029評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異新啼,居然都是意外死亡追城,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,395評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)燥撞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)座柱,“玉大人,你說(shuō)我怎么就攤上這事物舒∩矗” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,570評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵冠胯,是天一觀的道長(zhǎng)火诸。 經(jīng)常有香客問(wèn)我,道長(zhǎng)荠察,這世上最難降的妖魔是什么置蜀? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,535評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮悉盆,結(jié)果婚禮上盯荤,老公的妹妹穿的比我還像新娘。我一直安慰自己舀瓢,他們只是感情好廷雅,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,650評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布耗美。 她就那樣靜靜地躺著京髓,像睡著了一般。 火紅的嫁衣襯著肌膚如雪商架。 梳的紋絲不亂的頭發(fā)上堰怨,一...
    開(kāi)封第一講書(shū)人閱讀 49,850評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音蛇摸,去河邊找鬼备图。 笑死,一個(gè)胖子當(dāng)著我的面吹牛赶袄,可吹牛的內(nèi)容都是我干的揽涮。 我是一名探鬼主播,決...
    沈念sama閱讀 39,006評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼饿肺,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼蒋困!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起敬辣,我...
    開(kāi)封第一講書(shū)人閱讀 37,747評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤雪标,失蹤者是張志新(化名)和其女友劉穎零院,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體村刨,經(jīng)...
    沈念sama閱讀 44,207評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡告抄,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,536評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了嵌牺。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片打洼。...
    茶點(diǎn)故事閱讀 38,683評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖逆粹,靈堂內(nèi)的尸體忽然破棺而出拟蜻,到底是詐尸還是另有隱情,我是刑警寧澤枯饿,帶...
    沈念sama閱讀 34,342評(píng)論 4 330
  • 正文 年R本政府宣布酝锅,位于F島的核電站,受9級(jí)特大地震影響奢方,放射性物質(zhì)發(fā)生泄漏搔扁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,964評(píng)論 3 315
  • 文/蒙蒙 一蟋字、第九天 我趴在偏房一處隱蔽的房頂上張望稿蹲。 院中可真熱鬧,春花似錦鹊奖、人聲如沸苛聘。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,772評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)设哗。三九已至,卻和暖如春两蟀,著一層夾襖步出監(jiān)牢的瞬間网梢,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,004評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工赂毯, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留战虏,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,401評(píng)論 2 360
  • 正文 我出身青樓党涕,卻偏偏與公主長(zhǎng)得像烦感,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子膛堤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,566評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容