摘要:為了通過信號量,線程通過調用請求許可。許可的數目是固定的,由此限制了線程通過的數量。當設置為時默認也是,此類不對線程獲取許可的順序做任何保證。
【同步器
java.util.concurrent包包含幾個能幫助人們管理相互合作的線程集的類。這些機制具有為線程直間的共用集結點模式提供的‘預制功能’。如果有一個相互合作的線程滿足這些行為模式之一,那么應該直接使用提供的類庫而不是顯示的使用鎖與條件的集合。
【信號量一個信號量管理過個許可證。為了通過信號量,線程通過調用acquire()請求許可。其實沒有實際的許可對象,信號連也僅僅是維護一個計數器。許可的數目是固定的,由此限制了線程通過的數量。當一個線程執行完之后,應該調用release()釋放許可證,讓其他線程有機會執行。事實上,任意一個線程都有可以釋放任意個數的許可證,這可能會增加許可證的個數。所以我建議,如果不是非常明確的知道為什么要釋放多個許可證,就一定是讓獲得許可證的線程是放一個許可證。
【常用方法構造函數:
- Semaphore(int permits):創建具有給定許可數和非公平設置的Semaphore
- Semaphore(int permits,boolean fair):此類的構造方法可選地接受一個公平 參數。當設置為 false 時(默認也是false),此類不對線程獲取許可的順序做任何保證。特別地,闖入是允許的,也就是說可以在已經等待的線程前為調用 acquire() 的線程分配一個許可,從邏輯上說,就是新線程將自己置于等待線程隊列的頭部。當公平設置為 true 時,信號量保證對于任何調用獲取方法的線程而言,都按照處理它們調用這些方法的順序(即先進先出;FIFO)來選擇線程、獲得許可。注意,FIFO 排序必然應用到這些方法內的指定內部執行點。所以,可能某個線程先于另一個線程調用了 acquire,但是卻在該線程之后到達排序點,并且從方法返回時也類似。
2. Semaphore還提供一些其他方法:
- int availablePermits() :返回此信號量中當前可用的許可證數。 - int getQueueLength():返回正在等待獲取許可證的線程數。 - boolean hasQueuedThreads() :是否有線程正在等待獲取許可證。 - void reducePermits(int reduction) :減少reduction個許可證。是個protected方法。 - Collection getQueuedThreads() :返回所有等待獲取許可證的線程集合。是個protected方法。
當許可證的個數為1時,可以充當互斥鎖使用。
【例子:只能同時有5個線程訪問的信號量import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; public class SemaTest { public static void main(String[] args) throws InterruptedException { // 線程池 ExecutorService exec = Executors.newFixedThreadPool(20); // 只能5個線程同時訪問 final Semaphore semp = new Semaphore(5); // 模擬20個客戶端訪問 for (int index = 0; index < 20; index++) { final int NO = index; Runnable run = new Runnable() { public void run() { try { //記住這里需要使用while,如果直接用if判斷,那么每個線程只有一次機會去嘗試占有對象 while (1 == 1){ // 獲取許可 if(semp.tryAcquire()) { System.out.println(Thread.currentThread().getName() + " 【 Access: " + NO); Thread.sleep(100); // 訪問完后,釋放 semp.release(); System.out.println(Thread.currentThread().getName() + " 【 Release: " + NO); System.out.println("----------------- 【 " + Thread.currentThread().getName() + "】" + semp.availablePermits()); break; }else{ System.out.println(Thread.currentThread().getName() + " 【 NOT Access: " + NO); Thread.sleep(100); } } } catch (Exception e) { e.printStackTrace(); } } }; exec.execute(run); } //讓子線程有充分時間運行完 Thread.sleep(1000); exec.shutdown(); } }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/68091.html
摘要:創建線程的方式方式一將類聲明為的子類。將該線程標記為守護線程或用戶線程。其中方法隱含的線程為父線程。恢復線程,已過時。等待該線程銷毀終止。更多的使當前線程在鎖存器倒計數至零之前一直等待,除非線 知識體系圖: showImg(https://segmentfault.com/img/bVbef6v?w=1280&h=960); 1、線程是什么? 線程是進程中獨立運行的子任務。 2、創建線...
摘要:本文探討并發中的其它問題線程安全可見性活躍性等等。當閉鎖到達結束狀態時,門打開并允許所有線程通過。在從返回時被叫醒時,線程被放入鎖池,與其他線程競爭重新獲得鎖。 本文探討Java并發中的其它問題:線程安全、可見性、活躍性等等。 在行文之前,我想先推薦以下兩份資料,質量很高:極客學院-Java并發編程讀書筆記-《Java并發編程實戰》 線程安全 《Java并發編程實戰》中提到了太多的術語...
摘要:并發編程導論是對于分布式計算并發編程系列的總結與歸納。并發編程導論隨著硬件性能的迅猛發展與大數據時代的來臨,并發編程日益成為編程中不可忽略的重要組成部分。并發編程復興的主要驅動力來自于所謂的多核危機。 并發編程導論是對于分布式計算-并發編程 https://url.wx-coder.cn/Yagu8 系列的總結與歸納。歡迎關注公眾號:某熊的技術之路。 showImg(https://...
閱讀 1439·2021-11-11 16:54
閱讀 9322·2021-11-02 14:44
閱讀 2371·2021-10-22 09:53
閱讀 3259·2019-08-30 11:18
閱讀 1951·2019-08-29 13:29
閱讀 2003·2019-08-27 10:58
閱讀 1623·2019-08-26 11:38
閱讀 3518·2019-08-26 10:31