Java并發(fā)編程信號(hào)量Semapher
Semapher
信號(hào)量也是Java中的一個(gè)同步器,與CountDownLatch和CycleBarrier不同的是,它內(nèi)部的計(jì)數(shù)器是遞增的,并且在一開始初始化Semaphoer時(shí)可以指定一個(gè)初始值,但是并不需要知道需要同步的線程個(gè)數(shù),而是在需要同步的地方調(diào)用acquire方法時(shí)指定需要同步的線程個(gè)數(shù)。
我們通過下面一個(gè)例子來看一下Semapher效果:
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; public class SemaphoreTest { private static Semaphore semaphore = new Semaphore(0); public static void main(String[] args) throws InterruptedException{ ExecutorService executorService = Executors.newFixedThreadPool(2); executorService.submit(new Runnable() { @Override public void run() { try { System.out.println(Thread.currentThread() + "over"); semaphore.release(); } catch (Exception e) { e.printStackTrace(); } } }); executorService.submit(new Runnable() { @Override public void run() { try { System.out.println(Thread.currentThread() + "over"); semaphore.release(); } catch (Exception e) { e.printStackTrace(); } } }); semaphore.acquire(2); System.out.println("all child thread over!"); executorService.shutdown(); } }
如上代碼首先創(chuàng)建了一個(gè)信號(hào)量實(shí)例,構(gòu)造函數(shù)的入?yún)?,說明當(dāng)前信號(hào)量計(jì)數(shù)器的值為0。然后,main函數(shù)向線程池添加兩個(gè)線程任務(wù),在每個(gè)線程內(nèi)部調(diào)用信號(hào)量的acquire方法,傳參為2說明調(diào)用acquire方法的線程會(huì)一直阻塞,知道信號(hào)量的技術(shù)變?yōu)?才會(huì)返回。如果構(gòu)造Semaphore時(shí),傳遞的參數(shù)為N,并在M個(gè)線程中調(diào)用了該信號(hào)量的release方法,那么在調(diào)用acquire使M個(gè)線程同步時(shí)傳遞的參數(shù)應(yīng)該是M+N。
下面舉例子來模擬CycliBarrier復(fù)用的功能,代碼如下:
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; public class Semaphoer { private static Semaphore semaphore = new Semaphore(0); public static void main(String[] args) throws InterruptedException { ExecutorService executorService = Executors.newFixedThreadPool(2); executorService.submit(new Runnable() { @Override public void run() { try { System.out.println(Thread.currentThread() + "A task over"); semaphore.release(); } catch (Exception e) { e.printStackTrace(); } } }); executorService.submit(new Runnable() { @Override public void run() { try { System.out.println(Thread.currentThread() + "A task over"); semaphore.release(); } catch (Exception e) { e.printStackTrace(); } } }); semaphore.acquire(2); System.out.println("task A is over"); executorService.submit(new Runnable() { @Override public void run() { try { System.out.println(Thread.currentThread() + "B task over"); semaphore.release(); } catch (Exception e) { e.printStackTrace(); } } }); executorService.submit(new Runnable() { @Override public void run() { try { System.out.println(Thread.currentThread() + "B task over"); semaphore.release(); } catch (Exception e) { e.printStackTrace(); } } }); semaphore.acquire(2); System.out.println("task B is over"); executorService.shutdown(); } }
如上代碼首先將線程A和線程B加入到線程池。主線程執(zhí)行代碼(1)后被阻塞。線程A和線程B調(diào)用release
方法后信號(hào)量的值變?yōu)榱?,這時(shí)候主線程的aquire方法會(huì)在獲取到2個(gè)信號(hào)量后返回(返回后當(dāng)前信號(hào)量值為0)。然后主線程添加線程C和線程D到線程池,之后主線程執(zhí)行代碼(2)后被阻塞(因?yàn)橹骶€程要獲取2個(gè)信號(hào)量,而當(dāng)前信號(hào)量個(gè)數(shù)為0)。當(dāng)線程C和線程D執(zhí)行完release 方法后,主線程才返回。從本例子可以看出,Semaphore
在某種程度上實(shí)現(xiàn)了CyclicBarrier 的復(fù)用功能。
到此這篇關(guān)于Java并發(fā)編程信號(hào)量Semapher的文章就介紹到這了,更多相關(guān)Java Semapher內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用SpringBoot實(shí)現(xiàn)微服務(wù)超時(shí)重試模式的示例
這篇文章主要介紹了使用SpringBoot實(shí)現(xiàn)微服務(wù)超時(shí)重試模式的示例,幫助大家更好的理解和使用springboot框架,感興趣的朋友可以了解下2020-11-11java通過URLClassLoader類加載器加載外部jar代碼示例
ClassLoader翻譯過來就是類加載器,普通的java開發(fā)者其實(shí)用到的不多,但對(duì)于某些框架開發(fā)者來說卻非常常見,下面這篇文章主要給大家介紹了關(guān)于java通過URLClassLoader類加載器加載外部jar的相關(guān)資料,需要的朋友可以參考下2024-01-01SpringCloud超詳細(xì)講解微服務(wù)網(wǎng)關(guān)Zuul基礎(chǔ)
這篇文章主要介紹了SpringCloud?Zuul微服務(wù)網(wǎng)關(guān),負(fù)載均衡,熔斷和限流,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-10-10詳解Java如何判斷ResultSet結(jié)果集是否為空
ResultSet 表示 select 語句的查詢結(jié)果集。這篇文章主要為大家詳細(xì)介紹了Java如何判斷ResultSet結(jié)果集是否為空,感興趣的可以了解一下2023-02-02java中基本數(shù)據(jù)類型與Object的關(guān)系說明
這篇文章主要介紹了java基本數(shù)據(jù)類型與Object的關(guān)系說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03Maven的生命周期與自定義插件實(shí)現(xiàn)方法
Maven的生命周期就是對(duì)所有的構(gòu)建過程進(jìn)行抽象和統(tǒng)一。包含了項(xiàng)目的清理、初始化、編譯、測(cè)試、打包、集成測(cè)試、驗(yàn)證、部署和站點(diǎn)生成等幾乎所有的構(gòu)建步驟2022-12-12關(guān)于Jackson的JSON工具類封裝 JsonUtils用法
這篇文章主要介紹了關(guān)于Jackson的JSON工具類封裝 JsonUtils用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-09-09SpringSecurity實(shí)現(xiàn)動(dòng)態(tài)url攔截(基于rbac模型)
本文主要介紹了SpringSecurity動(dòng)態(tài)url攔截,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08java調(diào)用opencv身份證號(hào)識(shí)別詳解
這篇文章主要為大家詳細(xì)介紹了java如何調(diào)用opencv實(shí)現(xiàn)身份證號(hào)的識(shí)別,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-03-03