介紹 信號量(Semaphore),有時被稱為信號燈,是在多線程環境下使用的一種設施, 它負責協調各個線程, 以保證它們能夠正確、合理的使用公共資源。 概念 Semaphore分為單值和多值兩種,前者只能被一個線程獲得,後者可以被若幹個線程獲得。 Semaphore當前在多線程環境下被擴放使用,操作
- 介紹
信號量(Semaphore),有時被稱為信號燈,是在多線程環境下使用的一種設施, 它負責協調各個線程, 以保證它們能夠正確、合理的使用公共資源。
- 概念
Semaphore分為單值和多值兩種,前者只能被一個線程獲得,後者可以被若幹個線程獲得。
Semaphore當前在多線程環境下被擴放使用,操作系統的信號量是個很重要的概念,在進程式控制制方面都有應用。Java併發庫Semaphore 可以很輕鬆完成信號量控制,Semaphore可以控制某個資源可被同時訪問的個數,通過 acquire() 獲取一個許可,如果沒有就等待,而 release() 釋放一個許可。比如在Windows下可以設置共用文件的最大客戶端訪問個數。
單個信號量的Semaphore對象可以實現互斥鎖的功能,並且可以是由一個線程獲得了“鎖”,再由另一個線程釋放“鎖”,這可應用於死鎖恢復的一些場合。
- 實例
現在有一個三個信號燈,啟動10個線程分別獲取信號燈,當信號燈被占用時,其他線程只能等待,當信號燈被釋放則等待線程獲取信號燈。
1 public class SemaphoreTest { 2 public static void main(String[] args) { 3 ExecutorService pool = Executors.newCachedThreadPool(); 4 final Semaphore semaphore = new Semaphore(3,true); 5 6 for (int i = 0; i < 10; i++) { 7 Runnable runnable = new Runnable() { 8 @Override 9 public void run() { 10 try { 11 semaphore.acquire();//獲取信號燈許可 12 } catch (InterruptedException e) { 13 // TODO Auto-generated catch block 14 e.printStackTrace(); 15 } 16 System.out.println("Thread "+Thread.currentThread().getName()+" 進入" +"當前系統的併發數是:"+(3-semaphore.availablePermits())); 17 try { 18 Thread.sleep(new Random().nextInt(1000)); 19 } catch (InterruptedException e) { 20 // TODO Auto-generated catch block 21 e.printStackTrace(); 22 } 23 System.out.println("Thread "+Thread.currentThread().getName()+" 即將離開"); 24 semaphore.release();//釋放信號燈 25 System.out.println("Thread "+Thread.currentThread().getName()+" 已經離開,當前系統的併發數是:"+(3-semaphore.availablePermits())); 26 } 27 }; 28 pool.execute(runnable); 29 30 } 31 } 32 }
另外需要註意的一點是,信號燈可以由一個線程使用,然後由另一個線程來進行釋放,而鎖只能由同一個線程啟動和釋放,不然就好發生死鎖,這一點需要格外註意。