最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java信號量全解析

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

前言:

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

內(nèi)容主題:

一、簡單的Semaphore實現(xiàn)

下面是一個信號量的簡單實現(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ā)出一個被存放在Semaphore內(nèi)部的信號,而Release方法則等待一個信號,當其接收到信號后,標記位signal被清空,然后該方法終止。

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

當用semaphore來產(chǎn)生信號時,take和release這兩個方法名看起來有點奇怪。這兩個名字來源于后面把semaphore當做鎖的例子,后面會詳細介紹這個例子,在該例子中,take和release這兩個名字會變得很合理。

二、使用Semaphore來產(chǎn)生信號

下面的例子中,兩個線程通過Semaphore發(fā)出的信號來通知對方

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...
}
}
}

三、可計數(shù)的Semaphore

上面提到的Semaphore的簡單實現(xiàn)并沒有計算通過調(diào)用take方法所產(chǎn)生信號的數(shù)量??梢园阉脑斐删哂杏嫈?shù)功能的Semaphore。下面是一個可計數(shù)的Semaphore的簡單實現(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并沒有限制信號的數(shù)量。下面的代碼將CountingSemaphore改造成一個信號數(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中,當已經(jīng)產(chǎn)生的信號數(shù)量達到了上限,take方法將阻塞新的信號產(chǎn)生請求,直到某個線程調(diào)用release方法后,被阻塞于take方法的線程才能傳遞自己的信號。

五、把Semaphore當鎖來使用

當信號量的數(shù)量上限是1時,Semaphore可以被當做鎖來使用。通過take和release方法來保護關鍵區(qū)域。請看下面的例子:

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

在前面的例子中,Semaphore被用來在多個線程之間傳遞信號,這種情況下,take和release分別被不同的線程調(diào)用。但是在鎖這個例子中,take和release方法將被同一線程調(diào)用,因為只允許一個線程來獲取信號(允許進入關鍵區(qū)域的信號),其它調(diào)用take方法獲取信號的線程將被阻塞,知道第一個調(diào)用take方法的線程調(diào)用release方法來釋放信號。對release方法的調(diào)用永遠不會被阻塞,這是因為任何一個線程都是先調(diào)用take方法,然后再調(diào)用release。

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

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

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

相關文章

  • Java中byte、byte數(shù)組與int、long的轉(zhuǎn)換詳解

    Java中byte、byte數(shù)組與int、long的轉(zhuǎn)換詳解

    這篇文章分別給大家介紹了Java中byte和int之間的轉(zhuǎn)換、Java中 byte數(shù)組和int之間的轉(zhuǎn)換、Java中byte數(shù)組和long之間的轉(zhuǎn)換以及整理了整體工具類的源碼,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-02-02
  • Java依賴倒轉(zhuǎn)原則_動力節(jié)點Java學院整理

    Java依賴倒轉(zhuǎn)原則_動力節(jié)點Java學院整理

    這篇文章主要介紹了Java依賴倒轉(zhuǎn)原則的定義及問題由來解決方案,感興趣的朋友一起看看吧
    2017-08-08
  • java中壓縮文件并下載的實例詳解

    java中壓縮文件并下載的實例詳解

    在本篇內(nèi)容里小編給大家整理的是一篇關于java中壓縮文件并下載的實例詳解內(nèi)容,有興趣的朋友們可以學習下。
    2021-02-02
  • 從try-with-resources到ThreadLocal,優(yōu)化你的代碼編寫方式

    從try-with-resources到ThreadLocal,優(yōu)化你的代碼編寫方式

    這篇文章主要為大家介紹了從try-with-resources到ThreadLocal,優(yōu)化代碼的編寫方式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-04-04
  • C語言指針數(shù)組案例詳解

    C語言指針數(shù)組案例詳解

    這篇文章主要介紹了C語言指針數(shù)組案例詳解,本文通過案例詳細的解釋了指針與數(shù)組的初始化還有關系與應用,需要的朋友可以參考下這篇文章
    2021-07-07
  • SpringBoot多數(shù)據(jù)源配置方式以及報錯問題的解決

    SpringBoot多數(shù)據(jù)源配置方式以及報錯問題的解決

    這篇文章主要介紹了SpringBoot多數(shù)據(jù)源配置方式以及報錯問題的解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • 基于HashMap遍歷和使用方法(詳解)

    基于HashMap遍歷和使用方法(詳解)

    下面小編就為大家?guī)硪黄贖ashMap遍歷和使用方法(詳解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • Java Socket一對多通信實現(xiàn)之并發(fā)處理方式

    Java Socket一對多通信實現(xiàn)之并發(fā)處理方式

    這篇文章主要介紹了Java Socket一對多通信實現(xiàn)之并發(fā)處理方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • Springboot web項目打包實現(xiàn)過程解析

    Springboot web項目打包實現(xiàn)過程解析

    這篇文章主要介紹了Springboot web項目打包實現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-08-08
  • 關于Java中方法引用的示例

    關于Java中方法引用的示例

    方法引用可以認為是Lambda表達式的一種特殊形式,Lambda表達式可以讓開發(fā)者自定義抽象方法的實現(xiàn)代碼,方法引用則可以讓開發(fā)者直接引用已存在的實現(xiàn)方法,作為Lambda表達式的Lambda體(參數(shù)列表得一致),需要的朋友可以參考下
    2023-05-05

最新評論

炉霍县| 嘉兴市| 方城县| 永清县| 化德县| 南和县| 红原县| 桦甸市| 黑山县| 仙桃市| 靖远县| 关岭| 岳阳市| 佛教| 盐城市| 海林市| 黄平县| 丰镇市| 潮州市| 江华| 嘉兴市| 城口县| 志丹县| 霸州市| 小金县| 沙坪坝区| 临朐县| 蒙阴县| 肇源县| 晋宁县| 三穗县| 衡山县| 泸溪县| 车险| 安阳县| 毕节市| 怀远县| 大安市| 安平县| 云梦县| 枣阳市|