欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java信號(hào)量全解析

 更新時(shí)間:2021年01月22日 09:25:55   作者:無(wú)才的小易  
這篇文章主要介紹了Java信號(hào)量的相關(guān)資料,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下

前言:

Semaphore(信號(hào)量) 是一個(gè)線程同步結(jié)構(gòu),用于在線程間傳遞信號(hào),以避免出現(xiàn)信號(hào)丟失(譯者注:下文會(huì)具體介紹),或者像鎖一樣用于保護(hù)一個(gè)關(guān)鍵區(qū)域。自從5.0開(kāi)始,jdk在java.util.concurrent包里提供了Semaphore 的官方實(shí)現(xiàn),因此大家不需要自己去實(shí)現(xiàn)Semaphore。但是還是很有必要去熟悉如何使用Semaphore及其背后的原理

內(nèi)容主題:

一、簡(jiǎn)單的Semaphore實(shí)現(xiàn)

下面是一個(gè)信號(hào)量的簡(jiǎn)單實(shí)現(xiàn):

public class Semaphore {
private boolean signal = false;
public synchronized void take() {
this.signal = true;
this.notify();1011}
public synchronized void release() throws InterruptedException{
while(!this.signal) wait();
this.signal = false;
}
}

Take方法發(fā)出一個(gè)被存放在Semaphore內(nèi)部的信號(hào),而Release方法則等待一個(gè)信號(hào),當(dāng)其接收到信號(hào)后,標(biāo)記位signal被清空,然后該方法終止。

使用這個(gè)semaphore可以避免錯(cuò)失某些信號(hào)通知。用take方法來(lái)代替notify,release方法來(lái)代替wait。如果某線程在調(diào)用release等待之前調(diào)用take方法,那么調(diào)用release方法的線程仍然知道take方法已經(jīng)被某個(gè)線程調(diào)用過(guò)了,因?yàn)樵揝emaphore內(nèi)部保存了take方法發(fā)出的信號(hào)。而wait和notify方法就沒(méi)有這樣的功能。

當(dāng)用semaphore來(lái)產(chǎn)生信號(hào)時(shí),take和release這兩個(gè)方法名看起來(lái)有點(diǎn)奇怪。這兩個(gè)名字來(lái)源于后面把semaphore當(dāng)做鎖的例子,后面會(huì)詳細(xì)介紹這個(gè)例子,在該例子中,take和release這兩個(gè)名字會(huì)變得很合理。

二、使用Semaphore來(lái)產(chǎn)生信號(hào)

下面的例子中,兩個(gè)線程通過(guò)Semaphore發(fā)出的信號(hào)來(lái)通知對(duì)方

Semaphore semaphore = new Semaphore();
SendingThread sender = new SendingThread(semaphore);
ReceivingThread receiver = new ReceivingThread(semaphore);
receiver.start();
sender.start();
public class SendingThread {
Semaphore semaphore = null;
public SendingThread(Semaphore semaphore){
this.semaphore = semaphore;
}
public void run(){
while(true){
//do something, then signal
this.semaphore.take();
}
}
}
public class RecevingThread {
Semaphore semaphore = null;
public ReceivingThread(Semaphore semaphore){
this.semaphore = semaphore;
}
public void run(){
while(true){
this.semaphore.release();
//receive signal, then do something...
}
}
}

三、可計(jì)數(shù)的Semaphore

上面提到的Semaphore的簡(jiǎn)單實(shí)現(xiàn)并沒(méi)有計(jì)算通過(guò)調(diào)用take方法所產(chǎn)生信號(hào)的數(shù)量??梢园阉脑斐删哂杏?jì)數(shù)功能的Semaphore。下面是一個(gè)可計(jì)數(shù)的Semaphore的簡(jiǎn)單實(shí)現(xiàn)。

public class CountingSemaphore {
private int signals = 0;
public synchronized void take() {
this.signals++;0809this.notify();
}
public synchronized void release() throws InterruptedException{
while(this.signals == 0) wait();
this.signals--;
}
}

四、有上限的Semaphore

上面的CountingSemaphore并沒(méi)有限制信號(hào)的數(shù)量。下面的代碼將CountingSemaphore改造成一個(gè)信號(hào)數(shù)量有上限的BoundedSemaphore。

public class BoundedSemaphore {
private int signals = 0;
private int bound  = 0;
public BoundedSemaphore(int upperBound){
this.bound = upperBound;
}
public synchronized void take() throws InterruptedException{
while(this.signals == bound) wait();
this.signals++;
this.notify();
}
public synchronized void release() throws InterruptedException{
while(this.signals == 0) wait();
this.signals--;
this.notify();
}
}

在BoundedSemaphore中,當(dāng)已經(jīng)產(chǎn)生的信號(hào)數(shù)量達(dá)到了上限,take方法將阻塞新的信號(hào)產(chǎn)生請(qǐng)求,直到某個(gè)線程調(diào)用release方法后,被阻塞于take方法的線程才能傳遞自己的信號(hào)。

五、把Semaphore當(dāng)鎖來(lái)使用

當(dāng)信號(hào)量的數(shù)量上限是1時(shí),Semaphore可以被當(dāng)做鎖來(lái)使用。通過(guò)take和release方法來(lái)保護(hù)關(guān)鍵區(qū)域。請(qǐng)看下面的例子:

BoundedSemaphore semaphore = new BoundedSemaphore(1);
...
semaphore.take();
try{
//critical section
} finally {
semaphore.release();
}

在前面的例子中,Semaphore被用來(lái)在多個(gè)線程之間傳遞信號(hào),這種情況下,take和release分別被不同的線程調(diào)用。但是在鎖這個(gè)例子中,take和release方法將被同一線程調(diào)用,因?yàn)橹辉试S一個(gè)線程來(lái)獲取信號(hào)(允許進(jìn)入關(guān)鍵區(qū)域的信號(hào)),其它調(diào)用take方法獲取信號(hào)的線程將被阻塞,知道第一個(gè)調(diào)用take方法的線程調(diào)用release方法來(lái)釋放信號(hào)。對(duì)release方法的調(diào)用永遠(yuǎn)不會(huì)被阻塞,這是因?yàn)槿魏我粋€(gè)線程都是先調(diào)用take方法,然后再調(diào)用release。

通過(guò)有上限的Semaphore可以限制進(jìn)入某代碼塊的線程數(shù)量。設(shè)想一下,在上面的例子中,如果BoundedSemaphore 上限設(shè)為5將會(huì)發(fā)生什么?意味著允許5個(gè)線程同時(shí)訪問(wèn)關(guān)鍵區(qū)域,但是你必須保證,這個(gè)5個(gè)線程不會(huì)互相沖突。否則你的應(yīng)用程序?qū)⒉荒苷_\(yùn)行。

必須注意,release方法應(yīng)當(dāng)在finally塊中被執(zhí)行。這樣可以保在關(guān)鍵區(qū)域的代碼拋出異常的情況下,信號(hào)也一定會(huì)被釋放。

以上就是Java信號(hào)量全解析的詳細(xì)內(nèi)容,更多關(guān)于Java信號(hào)量的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Intellij?IDEA根據(jù)maven依賴(lài)名查找它是哪個(gè)pom.xml引入的(圖文詳解)

    Intellij?IDEA根據(jù)maven依賴(lài)名查找它是哪個(gè)pom.xml引入的(圖文詳解)

    這篇文章主要介紹了Intellij?IDEA根據(jù)maven依賴(lài)名查找它是哪個(gè)pom.xml引入的,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-08-08
  • Java并發(fā)容器之ConcurrentLinkedQueue詳解

    Java并發(fā)容器之ConcurrentLinkedQueue詳解

    這篇文章主要介紹了Java并發(fā)容器之ConcurrentLinkedQueue詳解,加鎖隊(duì)列的實(shí)現(xiàn)較為簡(jiǎn)單,這里就略過(guò),我們來(lái)重點(diǎn)來(lái)解讀一下非阻塞隊(duì)列,
    從點(diǎn)到面, 下面我們來(lái)看下非阻塞隊(duì)列經(jīng)典實(shí)現(xiàn)類(lèi)ConcurrentLinkedQueue,需要的朋友可以參考下
    2023-12-12
  • Java中的模板模式說(shuō)明與實(shí)現(xiàn)

    Java中的模板模式說(shuō)明與實(shí)現(xiàn)

    這篇文章主要介紹了Java中的模板模式說(shuō)明與實(shí)現(xiàn),模板方法模式,又叫模板模式,在一個(gè)抽象類(lèi)公開(kāi)定義了執(zhí)行它的方法的模板,它的子類(lèi)可以更需要重寫(xiě)方法實(shí)現(xiàn),但可以成為典型類(lèi)中定義的方式進(jìn)行,需要的朋友可以參考下
    2023-10-10
  • 使用JavaConfig代替xml實(shí)現(xiàn)Spring配置操作

    使用JavaConfig代替xml實(shí)現(xiàn)Spring配置操作

    這篇文章主要介紹了使用JavaConfig代替xml實(shí)現(xiàn)Spring配置操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • SpringBoot項(xiàng)目如何設(shè)置權(quán)限攔截器和過(guò)濾器

    SpringBoot項(xiàng)目如何設(shè)置權(quán)限攔截器和過(guò)濾器

    這篇文章主要介紹了使用lombok時(shí)如何自定義get、set方法問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • 關(guān)于SpringGateway調(diào)用服務(wù) 接受不到參數(shù)問(wèn)題

    關(guān)于SpringGateway調(diào)用服務(wù) 接受不到參數(shù)問(wèn)題

    這篇文章主要介紹了關(guān)于SpringGateway調(diào)用服務(wù)接受不到參數(shù)問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12
  • SpringBoot2.0整合WebSocket代碼實(shí)例

    SpringBoot2.0整合WebSocket代碼實(shí)例

    這篇文章主要介紹了SpringBoot2.0整合WebSocket代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • java中“==“和equals()的區(qū)別詳解

    java中“==“和equals()的區(qū)別詳解

    這篇文章主要給大家介紹了關(guān)于java中“==“和equals()區(qū)別的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • Java中內(nèi)部類(lèi)的概念與分類(lèi)詳解

    Java中內(nèi)部類(lèi)的概念與分類(lèi)詳解

    一個(gè)類(lèi)的定義放在另一個(gè)類(lèi)的內(nèi)部,這個(gè)類(lèi)就叫做內(nèi)部類(lèi),下面這篇文章主要給大家介紹了關(guān)于Java中內(nèi)部類(lèi)的概念與分類(lèi)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2021-09-09
  • Java使用FFmpeg處理視頻文件的方法教程

    Java使用FFmpeg處理視頻文件的方法教程

    這篇文章主要給大家介紹了關(guān)于Java使用FFmpeg處理視頻文件的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03

最新評(píng)論