執行緒(十四)執行緒同步技術Semaphore
阿新 • • 發佈:2018-11-08
理解:
Semaphore通常用於限制可以訪問某些資源(物理或邏輯的)的執行緒數目,我們可以自己設定最大訪問量。它有兩個很常用的方法是acquire()和release(),分別是獲得許可和釋放許可。
借用武哥的理解:
Semaphore相當於一個廁所,我在造的時候可以想造幾個坑就造幾個坑,假如現在我就造了3個坑,現在有10個人想要來上廁所,那麼每次就只能3個人上,誰最先搶到誰就進去,出來了一個人後,第4個人才能進去,這個就限制了上廁所的人數了,就這個道理。每個人上廁所之前都先acquire()一下,如果有坑,就可以進入,沒有就被阻塞,在外面等;上完廁所後,會release() 一下,釋放一個坑出來,以保證下一個人acquire()的時候有坑。
例項1:
public class SemaphoreTest { public static void main(String[] args) { ExecutorService service = Executors.newCachedThreadPool();//使用併發庫,建立快取的執行緒池 final Semaphore sp = new Semaphore(3);//建立一個Semaphore訊號量,並設定最大併發數為3 //availablePermits() //用來獲取當前可用的訪問次數 System.out.println("初始化:當前有" + (3 - sp.availablePermits() + "個併發")); //建立10個任務,上面的快取執行緒池就會建立10個對應的執行緒去執行 for (int index = 0; index < 10; index++) { final int NO = index; //記錄第幾個任務 Runnable run = new Runnable() { //具體任務 public void run() { try { sp.acquire(); // 獲取許可 System.out.println(Thread.currentThread().getName() + "獲取許可" + "("+NO+")," + "剩餘:" + sp.availablePermits()); Thread.sleep(1000); // 訪問完後記得釋放 ,否則在控制檯只能列印3條記錄,之後執行緒一直阻塞 sp.release(); //釋放許可 System.out.println(Thread.currentThread().getName() + "釋放許可" + "("+NO+")," + "剩餘:" + sp.availablePermits()); } catch (InterruptedException e) { } } }; service.execute(run); //執行任務 } service.shutdown(); //關閉執行緒池 } }