【Java併發程式設計】之二十三:併發新特性—訊號量Semaphore(含程式碼)
在作業系統中,訊號量是個很重要的概念,它在控制程序間的協作方面有著非常重要的作用,通過對訊號量的不同操作,可以分別實現程序間的互斥與同步。當然它也可以用於多執行緒的控制,我們完全可以通過使用訊號量來自定義實現類似Java中的synchronized、wait、notify機制。
Java併發包中的訊號量Semaphore實際上是一個功能完畢的計數訊號量,從概念上講,它維護了一個許可集合,對控制一定資源的消費與回收有著很重要的意義。Semaphore可以控制某個資源被同時訪問的任務數,它通過acquire()獲取一個許可,release()釋放一個許可。如果被同時訪問的任務數已滿,則其他acquire的任務進入等待狀態,直到有一個任務被release掉,它才能得到許可。
下面給出一個採用Semaphore控制併發訪問數量的示例程式:
某次執行的結果如下:import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; public class SemaphoreTest{ public static void main(String[] args) { //採用新特性來啟動和管理執行緒——內部使用執行緒池 ExecutorService exec = Executors.newCachedThreadPool(); //只允許5個執行緒同時訪問 final Semaphore semp = new Semaphore(5); //模擬10個客戶端訪問 for (int index = 0; index < 10; index++){ final int num = index; Runnable run = new Runnable() { public void run() { try { //獲取許可 semp.acquire(); System.out.println("執行緒" + Thread.currentThread().getName() + "獲得許可:" + num); //模擬耗時的任務 for (int i = 0; i < 999999; i++) ; //釋放許可 semp.release(); System.out.println("執行緒" + Thread.currentThread().getName() + "釋放許可:" + num); System.out.println("當前允許進入的任務個數:" + semp.availablePermits()); }catch(InterruptedException e){ e.printStackTrace(); } } }; exec.execute(run); } //關閉執行緒池 exec.shutdown(); } }
執行緒pool-1-thread-1獲得許可:0
執行緒pool-1-thread-1釋放許可:0
當前允許進入的任務個數:5
執行緒pool-1-thread-2獲得許可:1
執行緒pool-1-thread-6獲得許可:5
執行緒pool-1-thread-4獲得許可:3
執行緒pool-1-thread-8獲得許可:7
執行緒pool-1-thread-2釋放許可:1
當前允許進入的任務個數:2
執行緒pool-1-thread-5獲得許可:4
執行緒pool-1-thread-8釋放許可:7
執行緒pool-1-thread-3獲得許可:2
執行緒pool-1-thread-4釋放許可:3
執行緒pool-1-thread-10獲得許可:9
執行緒pool-1-thread-6釋放許可:5
執行緒pool-1-thread-10釋放許可:9
當前允許進入的任務個數:2
執行緒pool-1-thread-3釋放許可:2
當前允許進入的任務個數:1
執行緒pool-1-thread-5釋放許可:4
當前允許進入的任務個數:3
執行緒pool-1-thread-7獲得許可:6
執行緒pool-1-thread-9獲得許可:8
執行緒pool-1-thread-7釋放許可:6
當前允許進入的任務個數:5
當前允許進入的任務個數:3
當前允許進入的任務個數:3
當前允許進入的任務個數:3
執行緒pool-1-thread-9釋放許可:8
當前允許進入的任務個數:5
可以看出,Semaphore允許併發訪問的任務數一直為5,當然,這裡還很容易看出一點,就是Semaphore僅僅是對資源的併發訪問的任務數進行監控,而不會保證執行緒安全,因此,在訪問的時候,要自己控制執行緒的安全訪問。
相關推薦
【Java併發程式設計】之二十三:併發新特性—訊號量Semaphore(含程式碼)
在作業系統中,訊號量是個很重要的概念,它在控制程序間的協作方面有著非常重要的作用,通過對訊號量的不同操作,可以分別實現程序間的互斥與同步。當然它也可以用於多執行緒的控制,我們完全可以通過
【Java併發程式設計】之二十三:併發新特性—訊號量Semaphore(含程式碼)(r)
執行緒pool-1-thread-1獲得許可:0 執行緒pool-1-thread-1釋放許可:0 當前允許進入的任務個數:5 執行緒pool-1-thread-2獲得許可:1 執行緒pool-1-thread-6獲得許可:5 執行緒pool-1-thread-4獲得許可:3 執行緒pool-1-thread
【Java併發程式設計】之二十:併發新特性—Lock鎖和條件變數(含程式碼)
簡單使用Lock鎖 Java 5中引入了新的鎖機制——java.util.concurrent.locks中的顯式的互斥鎖:Lock介面,它提供了比synchronized更加廣泛的鎖定操作。Lock介面有3個實現它的類:ReentrantLock、Reetrant
【Java併發程式設計】之二十二:併發新特性—障礙器CyclicBarrier(含程式碼)
CyclicBarrier(又叫障礙器)同樣是Java 5中加入的新特性,使用時需要匯入java.util.concurrent.CylicBarrier。它適用於這樣一種情況:你希望建立一組任
【Java併發程式設計】之十六:深入Java記憶體模型——happen-before規則及其對DCL的分析(含程式碼)
happen—before規則介紹 Java語言中有一個“先行發生”(happen—before)的規則,它是Java記憶體模型中定義的兩項操作之間的偏序關係,如果操作A先行發生於操作B,其意思就是說,在發生操作B之前,操作A產生的影響都能被操作B觀察到,“影響
【搞定Java併發程式設計】第2篇:併發基礎概述
上一篇:執行緒的五種可用狀態 目 錄: 1、什麼是併發 2、Java的多執行緒和併發性 3、多執行緒的優點 4、多執行緒的代價 5、競態條件與臨界區 6、執行緒安全與共享資源 7、執行緒安全及不可變性 1、什麼是併發 在過去單CPU時代,單任務
【Java TCP/IP Socket】應用程式協議中訊息的成幀與解析(含程式碼)
程式間達成的某種包含了資訊交換的形式和意義的共識稱為協議,用來實現特定應用程式的協議叫做應用程式協議。大部分應用程式協議是根據由欄位序列組成的離散資訊定義的,其中每個欄位中都包含了一段以
深度學習系列文章之二上:win7+Ubantu雙系統裝機步驟(硬碟安裝)
一次上傳總是傳不上去,所以將安裝步驟分為上中下三篇上傳。 64位Win7系統下安裝ubantu14.04雙系統 一.安裝所需軟體 1、分割槽助手專業版(必需):用來對硬碟分割槽,將磁碟的一部分格式化成Linux可以識別的ext3格式。 2、Ext2Fsd(硬碟安裝必需,光
深度學習系列文章之二下:win7+Ubantu雙系統裝機步驟(硬碟安裝)
64位Win7系統下安裝ubantu14.04雙系統 三.開始安裝 1.如果是硬碟安裝,重啟後選擇NeoGrub引導進入。如果是光碟安裝,重啟後在啟動選項中選擇優先從光碟啟動並放入光碟從光碟啟動。 2、重新啟動並選擇NeoGrub Bootloader啟動項,進入ubu
【搞定Java併發程式設計】第17篇:佇列同步器AQS原始碼分析之共享模式
AQS系列文章: 1、佇列同步器AQS原始碼分析之概要分析 2、佇列同步器AQS原始碼分析之獨佔模式 3、佇列同步器AQS原始碼分析之共享模式 4、佇列同步器AQS原始碼分析之Condition介面、等待佇列 通過上一篇文章的的分析,我們知道獨佔模式獲取同步狀態(或者說獲取鎖
【搞定Java併發程式設計】第16篇:佇列同步器AQS原始碼分析之獨佔模式
AQS系列文章: 1、佇列同步器AQS原始碼分析之概要分析 2、佇列同步器AQS原始碼分析之獨佔模式 3、佇列同步器AQS原始碼分析之共享模式 4、佇列同步器AQS原始碼分析之Condition介面、等待佇列 本文主要講解佇列同步器AQS的獨佔模式:主要分為獨佔式同步狀態獲取
【搞定Java併發程式設計】第15篇:佇列同步器AQS原始碼分析之概要分析
AQS系列文章: 1、佇列同步器AQS原始碼分析之概要分析 2、佇列同步器AQS原始碼分析之獨佔模式 3、佇列同步器AQS原始碼分析之共享模式 4、佇列同步器AQS原始碼分析之Condition介面、等待佇列 先推薦兩篇不錯的博文: 1、一行一行原始碼分析清楚Abstract
【搞定Java併發程式設計】第18篇:佇列同步器AQS原始碼分析之Condition介面、等待佇列
AQS系列文章: 1、佇列同步器AQS原始碼分析之概要分析 2、佇列同步器AQS原始碼分析之獨佔模式 3、佇列同步器AQS原始碼分析之共享模式 4、佇列同步器AQS原始碼分析之Condition介面、等待佇列 通過前面三篇關於AQS文章的學習,我們深入瞭解了AbstractQ
【搞定Java併發程式設計】第27篇:Java中的併發工具類之執行緒間交換資料的 Exchanger
上一篇:Java中的併發工具類之控制併發執行緒數的 Semaphore Exchanger(交換者)是一個用於執行緒間協作的工具類。Exchanger用於進行執行緒間的資料交換。它提供一個同步點,在這個同步點,兩個執行緒可以交換彼此的資料。這兩個執行緒通過exchange方法交換資料,如果第一個
【搞定Java併發程式設計】第26篇:Java中的併發工具類之控制併發執行緒數的 Semaphore
上一篇:Java中的併發工具類之同步屏障 CyclicBarrier 本文目錄: 1、獲取許可證 2、釋放許可證 本文轉載自:https://mp.weixin.qq.com/s/LS8YBKpiJnHEY1kMWmwoxg 推薦閱讀:剖析基於併發AQS的共享鎖的實現(基於訊
【搞定Java併發程式設計】第25篇:Java中的併發工具類之同步屏障 CyclicBarrier
上一篇:Java中的併發工具類之CountDownLatch 本文目錄: 1、CyclicBarrier的簡單概述 2、CyclicBarrier 的原始碼分析 3、CyclicBarrier與CountDownLatch的區別 1、CyclicBarrier的簡單概述
【搞定Java併發程式設計】第24篇:Java中的併發工具類之CountDownLatch
上一篇:Java中的阻塞佇列 BlockingQueue 詳解 本文目錄: 1、CountDownLatch的基本概述 2、CountDownLatch的使用案例 3、CountDownLatch的原始碼分析 1、CountDownLatch的基本概述 Count
【搞定Java併發程式設計】第21篇:Java併發容器之ConcurrentHashMap詳解
上一篇:讀寫鎖 --- ReentrantReadWriteLock詳解 本文目錄: 1、為什麼要使用ConcurrentHashMap? 2、ConcurrentHashMap的實現 2.1、ConcurrentHashMap中主要的成員變數、成員方法和內部類 2.2、分段鎖的
【Java併發程式設計】之六:Runnable和Thread實現多執行緒的區別(含程式碼)
Java中實現多執行緒有兩種方法:繼承Thread類、實現Runnable介面,在程式開發中只要是多執行緒,肯定永遠以實現Runnable介面為主,因為實現Runnable介面相比繼承Th
【Java併發程式設計】之八:多執行緒環境中安全使用集合API(含程式碼)
在集合API中,最初設計的Vector和Hashtable是多執行緒安全的。例如:對於Vector來說,用來新增和刪除元素的方法是同步的。如果只有一個執行緒與Vector的例項互動,那麼,要求獲取