多執行緒與併發----Semaphere同步
Semaphore實現訊號燈:
Semaphore可以維護當前訪問自身的執行緒個數,並且提供了同步機制。使用Semaphore可以控制同時訪問資源的執行緒個數,例如,實現一個檔案允許的併發訪問數。
java.util.concurrent.Semaphore
一個計數訊號量。從概念上講,訊號量維護了一個許可集。如有必要,在許可可用前會阻塞每一個 acquire(),然後再獲取該許可。每個 release() 新增一個許可,從而可能釋放一個正在阻塞的獲取者。但是,不使用實際的許可物件,Semaphore 只對可用許可的號碼進行計數,並採取相應的行動。
Semaphore 通常用於限制可以訪問某些資源(物理或邏輯的)的執行緒數目。例如,下面的類使用訊號量控制對內容池的訪問:
獲得一項前,每個執行緒必須從訊號量獲取許可,從而保證可以使用該項。該執行緒結束後,將項返回到池中並將許可返回到該訊號量,從而允許其他執行緒獲取該項。注意,呼叫 acquire() 時無法保持同步鎖,因為這會阻止將項返回到池中。訊號量封裝所需的同步,以限制對池的訪問,這同維持該池本身一致性所需的同步是分開的。class Pool { private static final int MAX_AVAILABLE = 100; private final Semaphore available = new Semaphore(MAX_AVAILABLE, true); public Object getItem() throws InterruptedException { available.acquire(); return getNextAvailableItem(); } public void putItem(Object x) { if (markAsUnused(x)) available.release(); } // Not a particularly efficient data structure; just for demo protected Object[] items = ... whatever kinds of items being managed protected boolean[] used = new boolean[MAX_AVAILABLE]; protected synchronized Object getNextAvailableItem() { for (int i = 0; i < MAX_AVAILABLE; ++i) { if (!used[i]) { used[i] = true; return items[i]; } } return null; // not reached } protected synchronized boolean markAsUnused(Object item) { for (int i = 0; i < MAX_AVAILABLE; ++i) { if (item == items[i]) { if (used[i]) { used[i] = false; return true; } else return false; } } return false; } }
示例:3個燈 10個人
構造方法摘要
Semaphore(int permits) 建立具有給定的許可數和非公平的公平設定的 Semaphore。
Semaphore(int permits, boolean fair) 建立具有給定的許可數和給定的公平設定的 Semaphore。
方法摘要
void
void
acquire(int permits) 從此訊號量獲取給定數目的許可,在提供這些許可前一直將執行緒阻塞,或者執行緒已被中斷。
void
acquireUninterruptibly() 從此訊號量中獲取許可,在有可用的許可前將其阻塞。
void
acquireUninterruptibly(int permits) 從此訊號量獲取給定數目的許可,在提供這些許可前一直將執行緒阻塞。
int
availablePermits() 返回此訊號量中當前可用的許可數。
int
drainPermits() 獲取並返回立即可用的所有許可。
protected Collection<Thread>
getQueuedThreads() 返回一個 collection,包含可能等待獲取的執行緒。
int
getQueueLength() 返回正在等待獲取的執行緒的估計數目。
boolean
hasQueuedThreads() 查詢是否有執行緒正在等待獲取。
boolean
isFair() 如果此訊號量的公平設定為 true,則返回 true。
protected void
reducePermits(int reduction) 根據指定的縮減量減小可用許可的數目。
void
release() 釋放一個許可,將其返回給訊號量。
void
release(int permits) 釋放給定數目的許可,將其返回到訊號量。
toString() 返回標識此訊號量的字串,以及訊號量的狀態。
boolean
tryAcquire() 僅在呼叫時此訊號量存在一個可用許可,才從訊號量獲取許可。
boolean
tryAcquire(int permits) 僅在呼叫時此訊號量中有給定數目的許可時,才從此訊號量中獲取這些許可。
boolean
tryAcquire(int permits, long timeout, TimeUnit unit) 如果在給定的等待時間內此訊號量有可用的所有許可,並且當前執行緒未被中斷,則從此訊號量獲取給定數目的許可。
boolean
tryAcquire(long timeout, TimeUnit unit) 如果在給定的等待時間內,此訊號量有可用的許可並且當前執行緒未被中斷,則從此訊號量獲取一個許可。
房間,有多少人都能裝,執行緒數動態變化,來一個人產生一個執行緒
ExecutorService service = Exccutors.newCachedThreadPool(); final Semaphore sp = new Semaphore(3);燈的個數 指定只有3個 //3個燈,來了5個人,有2個人要等,其中有一個辦完事走了,等待的2個哪個先上呢?預設的構造方法不管,誰搶到了誰上。用new Semaphore(3, true)就可以保證先來的先上。 //將燈的個數設定為1就可以達到互斥效果,每次只能有一個執行緒執行 for (int i=0; i<10; i++)來了10個人 {//人的任務 搶燈 Runnable runnable = new Runnable() { public void run() { sp.acquire();//搶坑了 會拋中斷異常 }//有人佔住燈了,給出提示 SOP(currentThreadName+進入,當前已有(3-sp.availablePermits())個人了) Thread.sleep(5000)燈辦事 //辦完事打聲招呼 SOP(ThreadName即將離開) 釋放坑的佔有權 sp.release(); SOP(ThreadName已經走了,還有sp.availablePermits()個燈可用) } 開始任務吧 service.execute(runnable) }
傳統互斥只能內部釋放鎖this.unlock(),進去this.lock()暈倒了別人就沒法進去了;用訊號燈可以外部釋放,其他執行緒可以釋放再獲取sp.release() sp.acquire()。
相關文章
- 多執行緒與併發----CycliBarrier、CountDownLatch 和 Exchanger同步執行緒CountDownLatch
- 併發與多執行緒之執行緒安全篇執行緒
- 多執行緒與高併發(二)執行緒安全執行緒
- 多執行緒與高併發(一)多執行緒入門執行緒
- 併發與多執行緒基礎執行緒
- java多執行緒與併發 - 執行緒池詳解Java執行緒
- java多執行緒與併發 - 併發工具類Java執行緒
- 【多執行緒與高併發】- 執行緒基礎與狀態執行緒
- Java多執行緒與併發之ThreadLocalJava執行緒thread
- 多執行緒與併發----讀寫鎖執行緒
- 程式與執行緒、同步與非同步、阻塞與非阻塞、併發與並行執行緒非同步並行
- iOS 多執行緒--GCD 序列佇列、併發佇列以及同步執行、非同步執行iOS執行緒GC佇列非同步
- 多執行緒和多執行緒同步執行緒
- 多執行緒併發:以AQS中acquire()方法為例來分析多執行緒間的同步與協作執行緒AQSUI
- 【多執行緒總結(二)-執行緒安全與執行緒同步】執行緒
- JAVA多執行緒併發Java執行緒
- 多執行緒併發同步問題及解決方案執行緒
- 多執行緒併發篇——如何停止執行緒執行緒
- Dart 非同步與多執行緒Dart非同步執行緒
- 【多執行緒與高併發】- 淺談volatile執行緒
- Java高併發與多執行緒(一)-----概念Java執行緒
- 【多執行緒與高併發 2】volatile 篇執行緒
- 多執行緒與併發-----Lock鎖技術執行緒
- C#多執行緒開發-執行緒同步 02C#執行緒
- Java高併發與多執行緒(二)-----執行緒的實現方式Java執行緒
- Java多執行緒學習(3)執行緒同步與執行緒通訊Java執行緒
- Java併發指南1:併發基礎與Java多執行緒Java執行緒
- Java核心(三)併發中的執行緒同步與鎖Java執行緒
- 啃碎併發(六):Java執行緒同步與實現Java執行緒
- 分散式叢集與多執行緒高併發分散式執行緒
- JUC之Exchanger-多執行緒與高併發執行緒
- java併發程式設計——執行緒同步Java程式設計執行緒
- 一文講明白Java中執行緒與程序、併發與並行、同步與非同步Java執行緒並行非同步
- 程式執行緒、同步非同步、阻塞非阻塞、併發並行執行緒非同步並行
- java 多執行緒 –同步Java執行緒
- java 多執行緒 --同步Java執行緒
- 多執行緒併發執行及解決方法執行緒
- Python《多執行緒併發爬蟲》Python執行緒爬蟲