Java并發(fā)編程之Semaphore的使用簡介
Semaphore是用來限制訪問特定資源的并發(fā)線程的數量,相對于內置鎖synchronized和重入鎖ReentrantLock的互斥性來說,Semaphore可以允許多個線程同時訪問共享資源。
Semaphored的使用構造方法Semaphore(int permits):創(chuàng)建Semaphore,并指定許可證的數量。(公平策略為非公平)
Semaphore(int permits, boolean fair):創(chuàng)建Semaphore,并指定許可證的數量和公平策略。
核心方法acquire():從Semaphore中獲取一個許可證,如果獲取不到則阻塞等待,直到其他線程釋放了一個許可證或者當前線程被中斷。
acquire(int permits):從Semaphore中獲取指定數量的許可證,如果獲取不到則阻塞等待,直到其他線程釋放了對應數量的許可證或者當前線程被中斷。
acquireUninterruptibly():從Semaphore中獲取一個許可證,如果獲取不到則阻塞等待,直到其他線程釋放了一個許可證。(不響應中斷)
tryAcquire():嘗試從Semaphore中獲取一個許可證,獲取成功則返回true,獲取失敗則返回false,不會進行等待。(不受公平策略的影響,許可證可用則立即獲得)
tryAcquire(long timeout, TimeUnit unit):嘗試從Semaphore中獲取一個許可證,獲取成功則返回true,獲取失敗則等待指定的時間,直到等待時間結束還是沒有獲取到許可證則返回false。
release():釋放一個許可證。
release(int permits):釋放指定數量的許可證。
示例總共有5個許可證,最先獲取到許可證的5個線程開始執(zhí)行任務,沒獲取到的線程進入等待狀態(tài),直到獲取到許可證的線程釋放許可證后,再獲取許可證執(zhí)行任務。
public class Demo { public static void main(String[] args) {//創(chuàng)建許可證數量為5的SemaphoreSemaphore semaphore = new Semaphore(5);Runnable runnable = () -> { String threadName = Thread.currentThread().getName(); try{//獲取一個許可證semaphore.acquire();System.out.println(threadName + '執(zhí)行任務...');Thread.sleep(3000); } catch (InterruptedException e) {e.printStackTrace(); } finally {//釋放一個許可證semaphore.release(); }};ExecutorService executorService = Executors.newFixedThreadPool(10);for(int i = 0; i < 10; i++){ executorService.execute(runnable);}executorService.shutdown(); }}/* 開始輸出: * pool-1-thread-1執(zhí)行任務... * pool-1-thread-5執(zhí)行任務... * pool-1-thread-6執(zhí)行任務... * pool-1-thread-7執(zhí)行任務... * pool-1-thread-3執(zhí)行任務... * 三秒后輸出: * pool-1-thread-4執(zhí)行任務... * pool-1-thread-8執(zhí)行任務... * pool-1-thread-2執(zhí)行任務... * pool-1-thread-10執(zhí)行任務... * pool-1-thread-9執(zhí)行任務... */使用Semaphore實現(xiàn)互斥
使用Semaphore實現(xiàn)互斥只需要將許可證數量設置為1,這樣就可以保證只有一個線程能獲取到許可證。
Semaphore semaphore = new Semaphore(1);
相比內置鎖synchronized和重入鎖ReentrantLock,使用Semaphore實現(xiàn)互斥有個明顯的缺點:不可重入,沒有釋放許可證的情況下,再次調acquire方法將導致死鎖。
示例:
public class Demo { public static void main(String[] args) {Semaphore semaphore = new Semaphore(1);Runnable runnable = () -> { String threadName = Thread.currentThread().getName(); try {//獲取一個許可證semaphore.acquire();System.out.println(threadName + '執(zhí)行任務A...');semaphore.acquire();System.out.println(threadName + '執(zhí)行任務B...'); } catch (InterruptedException e) {e.printStackTrace(); } finally {//釋放一個許可證semaphore.release(); }};new Thread(runnable).start(); }}/* * 輸出結果: * Thread-0執(zhí)行任務A... */
“執(zhí)行任務B”永遠不會打印,因為許可證只有一個,第二次acquire方法的調用會因為無法獲取到許可證而一直阻塞。
以上就是Java并發(fā)編程之Semaphore的使用簡介的詳細內容,更多關于Java并發(fā)編程之Semaphore的資料請關注好吧啦網其它相關文章!
相關文章:
1. 解決docker與vmware的沖突問題2. Django中的AutoField字段使用3. Python基于jieba, wordcloud庫生成中文詞云4. IntelliJ Idea 2020.1 正式發(fā)布,官方支持中文(必看)5. IntelliJ IDEA設置自動提示功能快捷鍵的方法6. asp.net core應用docke部署到centos7的全過程7. Java 3D的動畫展示(Part1-使用JMF)8. Django ORM實現(xiàn)按天獲取數據去重求和例子9. Android 實現(xiàn)徹底退出自己APP 并殺掉所有相關的進程10. 刪除docker里建立容器的操作方法
