摘要:多線程同步工具箱之篇前言的多線程協(xié)調(diào)工具,,,都是在多線程代碼中使用比較多的工具類(lèi)之一。毫不夸張的說(shuō),這幾個(gè)類(lèi),是等同于解決多線程問(wèn)的包,實(shí)在有必要添加到程序員的工具箱里面。
Java多線程同步工具箱之CountDownLatch篇 前言
Java的多線程協(xié)調(diào)工具CountDownLatch,Semaphore,CyclicBarrier,ReadWriteLock都是在多線程代碼中使用比較多的工具類(lèi)之一。掌握及理解這幾個(gè)類(lèi)的實(shí)現(xiàn),對(duì)解決和理解多線程中復(fù)雜的業(yè)務(wù)狀況有很重要的作用。毫不夸張的說(shuō),這幾個(gè)類(lèi),是等同于解決多線程問(wèn)的java.util包,實(shí)在有必要添加到程序員的工具箱里面。
此次文章,將分幾篇總結(jié)及解讀一下這些工具類(lèi)的具體用法和范例,最后,希望可以再深入一點(diǎn)去理解這幾個(gè)多線程工具的實(shí)現(xiàn)。
1. CountDownLatch(倒數(shù)鎖)CountDownLatch是一個(gè)常用的多線程協(xié)調(diào)工具:主要為協(xié)調(diào)一個(gè)或多個(gè)線程完成后,主線程進(jìn)行某個(gè)操作的功能。
Latch原指門(mén)閂,CountDownLatch譯為倒數(shù)鎖倒是不太過(guò)分??梢岳斫鉃椋菏褂弥骶€程初始化一個(gè)有N個(gè)子鎖的鎖,任務(wù)開(kāi)始的時(shí),分配給N個(gè)線程每個(gè)線程持有一把鑰匙,每個(gè)線程到某個(gè)狀態(tài)后(一般為完成),可以使用線程持有的鑰匙打開(kāi)主線程持有的鎖,直至所有N個(gè)鎖都被打開(kāi),主線程才可以繼續(xù)其他任務(wù)。
1.1 API從API上看我們可以關(guān)注下面幾個(gè)CountDownLatch提供了幾個(gè)接口:
構(gòu)造方法CountDownLatch(int)
構(gòu)造方法十分簡(jiǎn)單,注入一個(gè)int,初始化倒數(shù)鎖的大小。
await()
等待所有鎖被解開(kāi),該函數(shù)還有一個(gè)帶等待時(shí)長(zhǎng)及等待時(shí)間單位的重寫(xiě)await(long time, TimeUnit unit),用于避免過(guò)度的等待造成的死鎖。
countDown()
解鎖方法,解開(kāi)一個(gè)鎖,知道持有的鎖數(shù)量為0,則接觸await的狀態(tài)。
getCount()
獲取當(dāng)前的剩余的鎖的數(shù)量。
1.2 范例在范例中,我們簡(jiǎn)單的使用一個(gè)主線程,發(fā)起若干個(gè)子線程,讓子線程進(jìn)行休眠的例子作為測(cè)試倒數(shù),讓各個(gè)子線程導(dǎo)數(shù)完通知解鎖,主線程會(huì)被在所有子線程完成解鎖后通知所有任務(wù)完成。
1.2.1 使用倒數(shù)鎖前import java.util.concurrent.CountDownLatch; import java.util.logging.Logger; public class App { static Logger log = Logger.getAnonymousLogger(); public static void main(String[] args) { for (int index = 0; index < 10; index++) { new Thread(new SubThread(index, index)).start(); } // 所有的線程都完成了 log.info("all thread finished"); } }
import java.util.concurrent.CountDownLatch; import java.util.logging.Logger; public class SubThread implements Runnable { private int id; private int waitSecond; static Logger log = Logger.getAnonymousLogger(); public SubThread(int id, int waitSecond) { this.id = id; // 秒數(shù)*1000毫秒 = 實(shí)際等待毫秒數(shù) this.waitSecond = waitSecond * 1000; } public void run() { try { log.info("Thread " + id + " started."); // 讓Thread再飛一會(huì)兒 Thread.sleep(waitSecond); log.info("Thread " + id + " end."); // 通知完成 } catch (InterruptedException e) { log.config("error"); } } }
可以從結(jié)果中看到,所有的線程啟動(dòng)后,主線程就會(huì)立刻退出,子線程會(huì)在完成各自的任務(wù)后再退出。
Aug 09, 2018 6:43:22 PM online.tangbk.demo.thead.SubThread run INFO: Thread 3 started. ... ... Aug 09, 2018 6:43:22 PM online.tangbk.demo.thead.App main INFO: all thread finished Aug 09, 2018 6:43:22 PM online.tangbk.demo.thead.SubThread run INFO: Thread 8 started. ... ... Aug 09, 2018 6:43:31 PM online.tangbk.demo.thead.SubThread run INFO: Thread 9 end.1.2.2 使用倒數(shù)鎖后
import java.util.concurrent.CountDownLatch; import java.util.logging.Logger; public class App { static Logger log = Logger.getAnonymousLogger(); public static void main(String[] args) { // 初始化10個(gè)線程的鎖 CountDownLatch cdl = new CountDownLatch(10); for (int index = 0; index < 10; index++) { // 將鎖傳給子線程 new Thread(new SubThread(index, index, cdl)).start(); } try { // 等待所有的鎖被(倒數(shù))釋放 cdl.await(); } catch (InterruptedException e) { e.printStackTrace(); } // 所有的線程都完成了 log.info("all thread finished"); } }
import java.util.concurrent.CountDownLatch; import java.util.logging.Logger; public class SubThread implements Runnable { private int id; private int waitSecond; private CountDownLatch cdl; static Logger log = Logger.getAnonymousLogger(); public SubThread(int id, int waitSecond, CountDownLatch cdl) { this.id = id; // 秒數(shù)*1000毫秒 = 實(shí)際等待毫秒數(shù) this.waitSecond = waitSecond * 1000; this.cdl = cdl; } public void run() { try { log.info("Thread " + id + " started."); // 讓Thread再飛一會(huì)兒 Thread.sleep(waitSecond); cdl.countDown(); log.info("Thread " + id + " end."); // 通知完成 } catch (InterruptedException e) { log.config("error"); } } }
可以從結(jié)果中看到,所有的線程啟動(dòng)后,都會(huì)等到所有線程完成等待后才結(jié)束。
Aug 09, 2018 6:29:20 PM online.tangbk.demo.thead.SubThread run INFO: Thread 2 started. Aug 09, 2018 6:29:20 PM online.tangbk.demo.thead.SubThread run INFO: Thread 3 started. Aug 09, 2018 6:29:20 PM online.tangbk.demo.thead.SubThread run INFO: Thread 1 started. Aug 09, 2018 6:29:20 PM online.tangbk.demo.thead.SubThread run INFO: Thread 0 started. ... ... Aug 09, 2018 6:29:28 PM online.tangbk.demo.thead.SubThread run INFO: Thread 8 end. Aug 09, 2018 6:29:29 PM online.tangbk.demo.thead.SubThread run INFO: Thread 9 end. Aug 09, 2018 6:29:29 PM online.tangbk.demo.thead.App main INFO: all thread finished1.3 CountDownLatch小結(jié)
CountDownLatch(倒數(shù)鎖)適用于需要等待子線程完成后,統(tǒng)一進(jìn)行操作的一些操作。更可以結(jié)合FutureTask的相關(guān)接口,取回子線程的結(jié)果,對(duì)結(jié)果統(tǒng)一搜集處理。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/76682.html
摘要:前言之前學(xué)多線程的時(shí)候沒(méi)有學(xué)習(xí)線程的同步工具類(lèi)輔助類(lèi)。而其它線程完成自己的操作后,調(diào)用使計(jì)數(shù)器減。信號(hào)量控制一組線程同時(shí)執(zhí)行。 前言 之前學(xué)多線程的時(shí)候沒(méi)有學(xué)習(xí)線程的同步工具類(lèi)(輔助類(lèi))。ps:當(dāng)時(shí)覺(jué)得暫時(shí)用不上,認(rèn)為是挺高深的知識(shí)點(diǎn)就沒(méi)去管了.. 在前幾天,朋友發(fā)了一篇比較好的Semaphore文章過(guò)來(lái),然后在瀏覽博客的時(shí)候又發(fā)現(xiàn)面試還會(huì)考,那還是挺重要的知識(shí)點(diǎn)。于是花了點(diǎn)時(shí)間去了解...
摘要:好了,繼續(xù)向下執(zhí)行,嘗試獲取鎖失敗后,會(huì)調(diào)用首先通過(guò)方法,將包裝成共享結(jié)點(diǎn),插入等待隊(duì)列,插入完成后隊(duì)列結(jié)構(gòu)如下然后會(huì)進(jìn)入自旋操作,先嘗試獲取一次鎖,顯然此時(shí)是獲取失敗的主線程還未調(diào)用,同步狀態(tài)還是。 showImg(https://segmentfault.com/img/remote/1460000016012541); 本文首發(fā)于一世流云的專(zhuān)欄:https://segmentfa...
摘要:在多線程編程中我們會(huì)遇到很多需要使用線程同步機(jī)制去解決的并發(fā)問(wèn)題,而這些同步機(jī)制就是多線程編程中影響正確性和運(yùn)行效率的重中之重。這五個(gè)方法之所以能指定同步器的行為,則是因?yàn)橹械钠渌椒ň褪峭ㄟ^(guò)對(duì)這五個(gè)方法的調(diào)用來(lái)實(shí)現(xiàn)的。 在多線程編程中我們會(huì)遇到很多需要使用線程同步機(jī)制去解決的并發(fā)問(wèn)題,而這些同步機(jī)制就是多線程編程中影響正確性和運(yùn)行效率的重中之重。這不禁讓我感到好奇,這些同步機(jī)制是如何...
摘要:前半句是指線程內(nèi)表現(xiàn)為串行的語(yǔ)義,后半句是指指令重排序現(xiàn)象和工作內(nèi)存和主內(nèi)存同步延遲現(xiàn)象。關(guān)于內(nèi)存模型的講解請(qǐng)參考死磕同步系列之。目前國(guó)內(nèi)市面上的關(guān)于內(nèi)存屏障的講解基本不會(huì)超過(guò)這三篇文章,包括相關(guān)書(shū)籍中的介紹。問(wèn)題 (1)volatile是如何保證可見(jiàn)性的? (2)volatile是如何禁止重排序的? (3)volatile的實(shí)現(xiàn)原理? (4)volatile的缺陷? 簡(jiǎn)介 volatile...
閱讀 3081·2021-11-24 11:14
閱讀 3525·2021-11-22 15:22
閱讀 3214·2021-09-27 13:36
閱讀 725·2021-08-31 14:29
閱讀 1335·2019-08-30 15:55
閱讀 1768·2019-08-29 17:29
閱讀 1153·2019-08-29 16:24
閱讀 2417·2019-08-26 13:48