1. 程式人生 > >【Java併發程式設計】之二十三:併發新特性—訊號量Semaphore(含程式碼)

【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的例項互動,那麼,要求獲取