Java併發編程之JUC輔助類Semaphore------信號量 一個例子看懂

一.場景引入


現在有6個車,要搶佔三個車位,佔用車位幾秒後,離開車位


二.代碼示例

public static void main(String[] args) {

        Semaphore semaphore = new Semaphore(3);

        for (int i = 1; i <= 6 ; i++) {

            new Thread(()->{

                try {
                    semaphore.acquire();

                    System.out.println(Thread.currentThread().getName()+"\t搶佔到了車位");

                    //暫停一會線程
                    TimeUnit.SECONDS.sleep(3);

                    System.out.println(Thread.currentThread().getName()+"\t離開了車位");

                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    semaphore.release();
                }

            },String.valueOf(i)).start();
        }
    }

運行結果:

"C:\Program Files\Java\jdk1.8.0_181\bin\java.exe" "-javaagent:D:\idea\IntelliJ IDEA 2019.2.3\lib\idea_rt.jar=56223:D:\idea\IntelliJ IDEA 2019.2.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_181\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\rt.jar;C:\Users\李肇京\IdeaProjects\JUC\out\production\JUC" JUC_01_SellTicket.HelperClasses.SemaphoreDemo
1	搶佔到了車位
2	搶佔到了車位
3	搶佔到了車位
1	離開了車位
4	搶佔到了車位
2	離開了車位
5	搶佔到了車位
3	離開了車位
6	搶佔到了車位
4	離開了車位
5	離開了車位
6	離開了車位

Process finished with exit code 0

三.Semaphore介紹

  • JDK官方:一個計數信號量。 在概念上,信號量維持一組許可
  • 在信號量上我們定義兩種操作:
    • acquire(獲取) 當一個線程調用acquire操作時,它要麼通過成功獲取信號量(信號量減1),要麼一直等下去,直到有線程釋放信號量,或超時
    • release(釋放)實際上會將信號量的值加1,然後喚醒等待的線程。

這裏我們通過信號量的構造方法傳入一個限制參數爲3,說明最多有三個線程佔用資源,acquire有兩種結果,一種是拿到信號量,信號量減一;要麼沒拿到,則阻塞。此處我們有三個車沒有拿到,爲阻塞狀態,但是當佔用車位的線程調用release後,之前沒進過車位的也有機會進入了。而且已經進過車位的線程因爲已經運行結束了,所以無法再次搶佔資源



  • 信號量主要用於兩個目的,一個是用於多個共享資源的互斥使用,另一個用於併發線程數的控制
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章