Java Semaphore用法
阿新 • • 發佈:2018-12-31
作業系統的訊號量是個很重要的概念,在程序控制方面都有應用。Java 併發庫 的Semaphore 可以很輕鬆完成訊號量控制,Semaphore可以控制某個資源可被同時訪問的個數,acquire()獲取一個許可,如果沒有就等待,而release()釋放一個許可。比如在Windows下可以設定共享檔案的最大客戶端訪問個數。
Semaphore維護了當前訪問的個數,提供同步機制,控制同時訪問的個數。在資料結構中連結串列可以儲存“無限”的節點,用Semaphore可以實現有限大小的連結串列。另外重入鎖ReentrantLock也可以實現該功能,但實現上要負責些,程式碼也要複雜些。
下面是模擬一個連線池,控制同一時間最多隻能有50個執行緒訪問。
import java.util.UUID; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; public class TestSemaphore extends Thread { public static void main(String[] args) { int i = 0; while (i < 500) { i++; new TestSemaphore().start(); try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } } /** * 控制某資源同時被訪問的個數的類 控制同一時間最後只能有50個訪問 */ static Semaphore semaphore = new Semaphore(50); static int timeout = 500; public void run() { try { Object connec = getConnection(); System.out.println("獲得一個連線" + connec); Thread.sleep(300); releaseConnection(connec); } catch (InterruptedException e) { e.printStackTrace(); } } public void releaseConnection(Object connec) { /* 釋放許可 */ semaphore.release(); System.out.println("釋放一個連線" + connec); } public Object getConnection() { try {/* 獲取許可 */ boolean getAccquire = semaphore.tryAcquire(timeout, TimeUnit.MILLISECONDS); if (getAccquire) { return UUID.randomUUID().toString(); } } catch (InterruptedException e) { e.printStackTrace(); } throw new IllegalArgumentException("timeout"); } }