同步工具之Semaphore實現信號燈

Semaphore(信號燈)是一個線程工具,Semaphore能夠控制同時訪問資源的個數,並提供了同步機制。假設有3個信號燈,3個信號燈都亮,那麼來的線程就能夠運行,每個線程運行,就會拿走一個信號燈,假如來了3個線程,那麼這3個信號燈就都被拿走了,其它再來的線程就等待。當執行的3個線程某個結束時,把信號燈還回來,那麼就能夠有新的線程繼續執行。例如,能夠實現一個文件容許的併發訪問數。假如一個文件只容許3個線程訪問,如今來了5個線程,另外2個只能等,看誰先把燈拿走,誰就先執行。看下面的例子。java

  • 1-1 一個Semaphore信號燈的例子
  •    
       
       
       
    1. import java.util.concurrent.ExecutorService; 
    2. import java.util.concurrent.Executors; 
    3. import java.util.concurrent.Semaphore; 
    4.  
    5. public class SemaphoreTest {//信號燈測試 
    6.     public static void main(String[] args) { 
    7.         ExecutorService service = Executors.newCachedThreadPool();//線程池,放10個任務,會開啓10個線程 
    8.         final  Semaphore sp = new Semaphore(3);//3個信號燈 
    9.         for(int i=0;i<10;i++){//往線程池中放進10個runnable(10個線程),每次只能進去(執行)3個 
    10.             Runnable runnable = new Runnable(){ 
    11.                     public void run(){ 
    12.                     try { 
    13.                         sp.acquire();//取得信號燈 
    14.                     } catch (InterruptedException e1) { 
    15.                         e1.printStackTrace(); 
    16.                     } 
    17.                     System.out.println("線程" + Thread.currentThread().getName() +  
    18.                             //3-sp.availablePermits()表示有幾個線程拿到了信號燈 
    19.                             "進入,當前已有" + (3-sp.availablePermits()) + "個併發"); 
    20.                     try { 
    21.                         Thread.sleep((long)(Math.random()*10000)); 
    22.                     } catch (InterruptedException e) { 
    23.                         e.printStackTrace(); 
    24.                     } 
    25.                     System.out.println("線程" + Thread.currentThread().getName() +  
    26.                             "即將離開");                     
    27.                     sp.release();//把信號燈還回來(釋放信號燈),,燈————和互斥很類似 
    28.                     //下面代碼有時候執行不許確,由於其沒有和上面的代碼合成原子單元 
    29.                     System.out.println("線程" + Thread.currentThread().getName() +  
    30.                             "已離開,當前已有" + (3-sp.availablePermits()) + "個併發");                     
    31.                 } 
    32.             }; 
    33.             service.execute(runnable);           
    34.         } 
    35.     } 

程序運行結果:併發

從運行結果能夠看到,每次最多有3個線程併發,由於只有3個信號燈。dom

總結:信號燈Semaphore,其實仍是互斥。單個信號的Semaphore對象能夠實現互斥鎖的功能,而且能夠是由一個線程得到的了「鎖」,再由另一個線程釋放「鎖」(注意互斥鎖,是誰上鎖,誰釋放,而信號燈能夠有其它的線程釋放),這可應用與死鎖恢復的一些場合。ide

相關文章
相關標籤/搜索