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í)任務(wù)兩種(Spring Schedule 與 Quartz 整合 )實(shí)現(xiàn)方法
本篇文章主要介紹了SpringBoot定時(shí)任務(wù)兩種(Spring Schedule 與 Quartz 整合 )實(shí)現(xiàn)方法,詳細(xì)的介紹了Spring Schedule 與 Quartz 整合的兩種方法,有興趣的可以了解一下。2017-03-03
AJAX省市區(qū)三級(jí)聯(lián)動(dòng)下拉菜單(java版)
這篇文章主要介紹了AJAX省市區(qū)三級(jí)聯(lián)動(dòng)下拉菜單(java版)的相關(guān)資料,需要的朋友可以參考下2016-01-01
java實(shí)現(xiàn)獲取安卓設(shè)備里已安裝的軟件包
本文給大家介紹的是如何獲取設(shè)備中已經(jīng)安裝的應(yīng)用軟件包的代碼,其核心方法原理很簡(jiǎn)單,我們通過Android中提供的PackageManager類,來獲取手機(jī)中安裝的應(yīng)用程序信息2015-10-10
Java8中Lambda表達(dá)式的理解與應(yīng)用
Java8最值得學(xué)習(xí)的特性就是Lambda表達(dá)式和Stream?API,如果有python或者javascript的語言基礎(chǔ),對(duì)理解Lambda表達(dá)式有很大幫助,下面這篇文章主要給大家介紹了關(guān)于Java8中Lambda表達(dá)式的相關(guān)資料,需要的朋友可以參考下2022-02-02
struts2中simple主題下<s:fieldError>標(biāo)簽?zāi)J(rèn)樣式的移除方法
這篇文章主要給大家介紹了關(guān)于struts2中simple主題下<s:fieldError>標(biāo)簽?zāi)J(rèn)樣式的移除方法,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-10-10

