国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

(八)java多線程之Semaphore

DesGemini / 2068人閱讀

摘要:在每個線程獲取之前,必須先從信號量獲取許可。注意,因為同時可能發(fā)生取消,所以返回并不保證有其他線程等待獲取許可。該值僅是估計的數(shù)字,因為在此方法遍歷內(nèi)部數(shù)據(jù)結(jié)構(gòu)的同時,線程的數(shù)目可能動態(tài)地變化。

本人郵箱:
歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明網(wǎng)址 http://blog.csdn.net/tianshi_kco
github: https://github.com/kco1989/kco
代碼已經(jīng)全部托管github有需要的同學(xué)自行下載

引言

這節(jié)課,我們就開始講一下信號量Semaphore

理論

Semaphore:一個可計數(shù)的信號量。一般,一個semaphore 信號量是一組許可證。如果必要,那個每次acquire獲取許可都是阻塞的,直接一個許可證是可用的,并獲取到。每次release釋放,都會增加一個許可證,潛在的,也會釋放一個阻塞請求。然而。并非每次許可對象都可以被使用的,這個Semaphore信號量只保存幾個可用的許可證和相應(yīng)的操作。

如果有幾個線程數(shù)要訪問幾個共享資源的話,那么這時候就應(yīng)該使用信號量。舉例說明:這個有類Pool類,它就使用信號量在控制多線程去訪問那么幾個有限items

class Pool {
   private static final int MAX_AVAILABLE = 100;
   private final Semaphore available = new Semaphore(MAX_AVAILABLE, true);

   public Object getItem() throws InterruptedException {
     available.acquire();
     return getNextAvailableItem();
   }

   public void putItem(Object x) {
     if (markAsUnused(x))
       available.release();
   }

   // Not a particularly efficient data structure; just for demo

   protected Object[] items = ... whatever kinds of items being managed
   protected boolean[] used = new boolean[MAX_AVAILABLE];

   protected synchronized Object getNextAvailableItem() {
     for (int i = 0; i < MAX_AVAILABLE; ++i) {
       if (!used[i]) {
          used[i] = true;
          return items[i];
       }
     }
     return null; // not reached
   }

   protected synchronized boolean markAsUnused(Object item) {
     for (int i = 0; i < MAX_AVAILABLE; ++i) {
       if (item == items[i]) {
          if (used[i]) {
            used[i] = false;
            return true;
          } else
            return false;
       }
     }
     return false;
   }
}

在每個線程獲取item之前,必須先從信號量獲取許可。保證這個item對用戶來說是可以使用的。當(dāng)線程結(jié)束使用item時,并讓item返回item池,這信號量會釋放這個許可,之后允許使用線程可以獲取到這個item。必須要注意的,在程序中,在獲取許可和釋放許可的死胡同并沒有使用同步鎖,信號量封裝了限制對池的訪問所需的同步,與維護(hù)池本身的一致性所需的任何同步。

Semaphore(int permits): 創(chuàng)建一個指定數(shù)量的許可的信號量

Semaphore(int permits, boolean fair) 創(chuàng)建一個指定數(shù)量的許可,并保證每個線程都是公平的,當(dāng)fairtrue時,信號量會安裝先進(jìn)先出的原則來獲取許可.

acquire() 在當(dāng)前信號量中獲取一個許可.當(dāng)前線程會一直阻塞直到有一個可用的許可,或被其他線程中斷.

acquireUninterruptibly(): 在當(dāng)前信號量中獲取一個許可.當(dāng)前線程會一直阻塞直到有一個可用的許可.

tryAcquire() 在當(dāng)前信號量嘗試獲取一個許可,如果有可用,則獲取到這個許可,并立即返回true,后綴立即返回false

tryAcquire 在當(dāng)前信號量獲取一個許可,當(dāng)前線程會一直阻塞直到有一個可用的許可.或指定時間超時了,或被其他線程中斷.

release() 釋放一個許可,把讓它返回到這個信號量中.

acquire(int permits) 請求指定數(shù)量的許可,如果有足夠的許可可用,那么當(dāng)前線程會立刻返回,如果許可不足,則當(dāng)前會一直等待,直到被其他線程中斷,或獲取到足夠的許可.

acquireUninterruptibly(int permits) 請求指定數(shù)量的許可,如果有足夠的許可可用,那么當(dāng)前線程會立刻返回,如果許可不足,則當(dāng)前會一直等待,直到獲取到足夠的許可.

tryAcquire(int permits) 在當(dāng)前信號量嘗試獲取指定數(shù)量的許可,如果有可用,則獲取到這個許可,并立即返回true,后綴立即返回false

tryAcquire(int permits, long timeout, TimeUnit unit) 在指定的超時時間,當(dāng)前信號量嘗試獲取指定數(shù)量的許可,如果有可用,則獲取到這個許可,并立即返回true,后綴立即返回false

release(int permits) 釋放指定數(shù)量的許可

availablePermits() 返回當(dāng)前信號量還有幾個可用的許可

drainPermits() 請求并立即返回當(dāng)前信號量可用的全部許可

reducePermits(int reduction) 根據(jù)指定的縮減量減小可用許可的數(shù)目。此方法在使用信號量來跟蹤那些變?yōu)椴豢捎觅Y源的子類中很有用。此方法不同于 acquire,在許可變?yōu)榭捎玫倪^程中,它不會阻塞等待。

isFair() 返回當(dāng)前的信號量時候是公平的

hasQueuedThreads() 查詢是否有線程正在等待獲取。注意,因為同時可能發(fā)生取消,所以返回 true 并不保證有其他線程等待獲取許可。此方法主要用于監(jiān)視系統(tǒng)狀態(tài)。

getQueueLength() 返回正在等待獲取的線程的估計數(shù)目。該值僅是估計的數(shù)字,因為在此方法遍歷內(nèi)部數(shù)據(jù)結(jié)構(gòu)的同時,線程的數(shù)目可能動態(tài)地變化。此方法用于監(jiān)視系統(tǒng)狀態(tài),不用于同步控制。

getQueuedThreads() 返回一個 collection,包含可能等待獲取的線程。因為在構(gòu)造此結(jié)果的同時實際的線程 set 可能動態(tài)地變化,所以返回的 collection 僅是盡力的估計值。所返回 collection 中的元素沒有特定的順序。此方法用于加快子類的構(gòu)造速度,提供更多的監(jiān)視設(shè)施。

例子

看了前面那么方法的介紹,恐怕你想吐的的心都有了吧?還是讓我們回歸輕松愉快的例子來吧.這里我們還是繼續(xù)舉小明小紅談人生和理想的例子.之前他們在臥室里談了好幾百毫秒的人生和理想.頓時都感覺身疲憊,感覺身體好像被掏空了一樣.所以這里他們都想洗一個熱水澡,但是沐浴室只有三間,那就搶吧..ok,開始編程...

首先,先編寫一個沐浴室ShowerRoom

public class ShowerRoom {
    private static final int MAX_SIZE = 3;
    Semaphore semaphore = new Semaphore(MAX_SIZE);

    public void bathe(String name){
        try {
            semaphore.acquire();
            System.out.println(Thread.currentThread().getName() + " 洗唰唰啊..洗唰唰... ");
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            System.out.println(Thread.currentThread().getName() + " 終于洗完澡了...");
            semaphore.release();
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

然后編寫讓小明小紅去洗澡操作 BoyAndGril

public class BoyAndGril implements Runnable{
    ShowerRoom showerRoom;
    public BoyAndGril(ShowerRoom showerRoom) {
        this.showerRoom = showerRoom;
    }

    @Override
    public void run() {
        String name = Thread.currentThread().getName();
        showerRoom.bathe(name);
    }
}

最后,測試一下

public class TestMain {

    public static void main(String[] args) {
        Set boyAndGril = new HashSet<>();
        ShowerRoom showerRoom = new ShowerRoom();
        for (int i = 0; i < 10; i ++){
            boyAndGril.add(new Thread(new BoyAndGril(showerRoom), "小明" + i + "號"));
        }
        for (int i = 0; i < 10; i ++){
            boyAndGril.add(new Thread(new BoyAndGril(showerRoom), "小紅" + i + "號"));
        }
        for (Thread thread : boyAndGril){
            thread.start();
        }
    }
}

運行一下結(jié)果

小紅3號 洗唰唰啊..洗唰唰... 
小紅6號 洗唰唰啊..洗唰唰... 
小明0號 洗唰唰啊..洗唰唰... 
小紅3號 終于洗完澡了...
小紅2號 洗唰唰啊..洗唰唰... 
小紅6號 終于洗完澡了...
小明2號 洗唰唰啊..洗唰唰... 
小明0號 終于洗完澡了...
小紅1號 洗唰唰啊..洗唰唰... 
小紅2號 終于洗完澡了...
小明5號 洗唰唰啊..洗唰唰... 
小明2號 終于洗完澡了...
小明7號 洗唰唰啊..洗唰唰... 
小紅1號 終于洗完澡了...
小紅0號 洗唰唰啊..洗唰唰... 
小明5號 終于洗完澡了...
小明7號 終于洗完澡了...
小明4號 洗唰唰啊..洗唰唰... 
小紅4號 洗唰唰啊..洗唰唰... 
小紅0號 終于洗完澡了...
小明3號 洗唰唰啊..洗唰唰... 
小明4號 終于洗完澡了...
小明9號 洗唰唰啊..洗唰唰... 
小紅4號 終于洗完澡了...
小紅7號 洗唰唰啊..洗唰唰... 
小明3號 終于洗完澡了...
小紅5號 洗唰唰啊..洗唰唰... 
小紅5號 終于洗完澡了...
小紅9號 洗唰唰啊..洗唰唰... 
小紅7號 終于洗完澡了...
小明6號 洗唰唰啊..洗唰唰... 
小明9號 終于洗完澡了...
小明1號 洗唰唰啊..洗唰唰... 
小紅9號 終于洗完澡了...
小紅8號 洗唰唰啊..洗唰唰... 
小明1號 終于洗完澡了...
小明8號 洗唰唰啊..洗唰唰... 
小明6號 終于洗完澡了...
小紅8號 終于洗完澡了...
小明8號 終于洗完澡了...

ok,運行正常,程序中不會發(fā)生四個人以及四個以上的人在同時洗澡的情況.

如果有人覺得這個好像也沒有使用什么共享資源啊,沒有上面那個例子的item pool,那行,那把有關(guān)semaphore的代碼注釋掉,再運行一下.

小紅3號 洗唰唰啊..洗唰唰... 
小紅6號 洗唰唰啊..洗唰唰... 
小明0號 洗唰唰啊..洗唰唰... 
小紅2號 洗唰唰啊..洗唰唰... 
小明2號 洗唰唰啊..洗唰唰... 
小紅1號 洗唰唰啊..洗唰唰... 
小明5號 洗唰唰啊..洗唰唰... 
小明7號 洗唰唰啊..洗唰唰... 
小紅0號 洗唰唰啊..洗唰唰... 
小明4號 洗唰唰啊..洗唰唰... 
小紅4號 洗唰唰啊..洗唰唰... 
小明3號 洗唰唰啊..洗唰唰... 
小明9號 洗唰唰啊..洗唰唰... 
小紅7號 洗唰唰啊..洗唰唰... 
小紅5號 洗唰唰啊..洗唰唰... 
小紅9號 洗唰唰啊..洗唰唰... 
小明6號 洗唰唰啊..洗唰唰... 
小明1號 洗唰唰啊..洗唰唰... 
小紅8號 洗唰唰啊..洗唰唰... 
小明8號 洗唰唰啊..洗唰唰... 
小紅3號 終于洗完澡了...
小紅2號 終于洗完澡了...
小明2號 終于洗完澡了...
小紅6號 終于洗完澡了...
小明0號 終于洗完澡了...
小明5號 終于洗完澡了...
小紅0號 終于洗完澡了...
小明7號 終于洗完澡了...
小紅1號 終于洗完澡了...
小明4號 終于洗完澡了...
小紅4號 終于洗完澡了...
小明3號 終于洗完澡了...
小明9號 終于洗完澡了...
小紅8號 終于洗完澡了...
小紅5號 終于洗完澡了...
小紅9號 終于洗完澡了...
小明6號 終于洗完澡了...
小明1號 終于洗完澡了...
小紅7號 終于洗完澡了...
小明8號 終于洗完澡了...

發(fā)現(xiàn)這幾十個人都同時在三間沐浴室里洗澡,那么肯定有只是一間會出現(xiàn)兩人或兩人以上同時洗澡的情況.如果浴室夠大,大家都沒有意見,那還好.就是如果肥皂掉了,這個時候,小明就得考慮要不要彎腰去撿了....

打賞

如果覺得我的文章寫的還過得去的話,有錢就捧個錢場,沒錢給我捧個人場(幫我點贊或推薦一下)

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/69898.html

相關(guān)文章

  • Java線程工具箱Semaphore

    摘要:多線程工具箱之前言這一篇談一下信號量。信息信息信息信息信息信息信息信息信息信息信息小結(jié)適用于多線程請求數(shù)量資源的場景,但無法解決單多個線程對同一資源訪問的競爭性訪問。在后面我們在我們的多線程工具箱里面陸續(xù)會提到。 Java多線程工具箱之Semaphore 前言 這一篇談一下Semaphore:信號量。 將Semaphore類比為為信號燈,被繼承Runable的線程類比為列車:理解信號量...

    FleyX 評論0 收藏0
  • Java線程進(jìn)階(二十)—— J.U.Csynchronizer框架:Semaphore

    摘要:當(dāng)線程使用完共享資源后,可以歸還許可,以供其它需要的線程使用。所以,并不會阻塞調(diào)用線程。立即減少指定數(shù)目的可用許可數(shù)。方法用于將可用許可數(shù)清零,并返回清零前的許可數(shù)六的類接口聲明類聲明構(gòu)造器接口聲明 showImg(https://segmentfault.com/img/bVbfdnC?w=1920&h=1200); 本文首發(fā)于一世流云的專欄:https://segmentfault...

    boredream 評論0 收藏0
  • Java線程&高并發(fā)

    摘要:線程啟動規(guī)則對象的方法先行發(fā)生于此線程的每一個動作。所以局部變量是不被多個線程所共享的,也就不會出現(xiàn)并發(fā)問題。通過獲取到數(shù)據(jù),放入當(dāng)前線程處理完之后將當(dāng)前線程中的信息移除。主線程必須在啟動其他線程后立即調(diào)用方法。 一、線程安全性 定義:當(dāng)多個線程訪問某個類時,不管運行時環(huán)境采用何種調(diào)度方式,或者這些線程將如何交替執(zhí)行,并且在主調(diào)代碼中不需要任何額外的同步或協(xié)同,這個類都能表現(xiàn)出正確的行...

    SQC 評論0 收藏0
  • Java線程編程同步器

    摘要:倒計時鎖,線程中調(diào)用使進(jìn)程進(jìn)入阻塞狀態(tài),當(dāng)達(dá)成指定次數(shù)后通過繼續(xù)執(zhí)行每個線程中剩余的內(nèi)容。實現(xiàn)分階段的的功能測試代碼拿客網(wǎng)站群三產(chǎn)創(chuàng)建于年月日。 同步器 為每種特定的同步問題提供了解決方案 Semaphore Semaphore【信號標(biāo);旗語】,通過計數(shù)器控制對共享資源的訪問。 測試類: package concurrent; import concurrent.th...

    liangdas 評論0 收藏0
  • 后臺開發(fā)常問面試題集錦(問題搬運工,附鏈接)

    摘要:基礎(chǔ)問題的的性能及原理之區(qū)別詳解備忘筆記深入理解流水線抽象關(guān)鍵字修飾符知識點總結(jié)必看篇中的關(guān)鍵字解析回調(diào)機(jī)制解讀抽象類與三大特征時間和時間戳的相互轉(zhuǎn)換為什么要使用內(nèi)部類對象鎖和類鎖的區(qū)別,,優(yōu)缺點及比較提高篇八詳解內(nèi)部類單例模式和 Java基礎(chǔ)問題 String的+的性能及原理 java之yield(),sleep(),wait()區(qū)別詳解-備忘筆記 深入理解Java Stream流水...

    spacewander 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<