java併發程式設計之Semaphore(訊號量)的用法
Semaphore類其實就是synchronized關鍵字的升級版,這個類主要作用就是控制執行緒併發的數量,而在這方面synchronized就有點力不足了,接下來我們就開始先了解一下Semaphore的一些常用方法就注意細節。
在new 這個類的時候需要給這個類傳遞一個引數permits,這個引數是整數型別,這個引數的意思是同一時間內,最多允許多少個執行緒同時執行acquire方法和release方法之間的程式碼,如果方法acquire沒有引數則預設是一個許可。下面我們用程式碼進行驗證。
Semaphore又稱訊號量,是作業系統中的一個概念,在Java併發程式設計中,訊號量控制的是執行緒併發的數量。
public Semaphore(int permits)
其中引數permits就是允許同時執行的執行緒數目;
下面先看一個訊號量實現單執行緒的例子,也就是permits=1:
package concurrent.semaphore; import java.util.concurrent.Semaphore; public class Driver { // 控制執行緒的數目為1,也就是單執行緒 private Semaphore semaphore = new Semaphore(1); public void driveCar() { try { // 從訊號量中獲取一個允許機會 semaphore.acquire(); System.out.println(Thread.currentThread().getName() + " start at " + System.currentTimeMillis()); Thread.sleep(1000); System.out.println(Thread.currentThread().getName() + " stop at " + System.currentTimeMillis()); // 釋放允許,將佔有的訊號量歸還 semaphore.release(); } catch (InterruptedException e) { e.printStackTrace(); } } }
package concurrent.semaphore;
public class Car extends Thread{
private Driver driver;
public Car(Driver driver) {
super();
this.driver = driver;
}
public void run() {
driver.driveCar();
}
}
public class Run { public static void main(String[] args) { Driver driver = new Driver(); for (int i = 0; i < 5; i++) { (new Car(driver)).start(); } } }
執行結果:
Thread-0 start at 1482664517179
Thread-0 stop at 1482664518179
Thread-3 start at 1482664518179
Thread-3 stop at 1482664519179
Thread-1 start at 1482664519179
Thread-1 stop at 1482664520179
Thread-4 start at 1482664520179
Thread-4 stop at 1482664521180
Thread-2 start at 1482664521180
Thread-2 stop at 1482664522180
從輸出可以看出,改輸出與單執行緒是一樣的,執行完一個執行緒,再執行另一個執行緒。
如果訊號量大於1呢,我們將訊號量設為3:
public class Driver {
// 將訊號量設為3
private Semaphore semaphore = new Semaphore(3);
public void driveCar() {
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + " start at " + System.currentTimeMillis());
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + " stop at " + System.currentTimeMillis());
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
輸出:
Thread-0 start at 1482665412515
Thread-3 start at 1482665412517
Thread-1 start at 1482665412517
Thread-3 stop at 1482665413517
Thread-0 stop at 1482665413517
Thread-4 start at 1482665413517
Thread-2 start at 1482665413517
Thread-1 stop at 1482665413518
Thread-4 stop at 1482665414517
Thread-2 stop at 1482665414517
從輸出的前三行可以看出,有3個執行緒可以同時執行,三個執行緒同時執行的時候,第四個執行緒必須等待前面有一個要完成,才能執行第四個執行緒啟動。
當然也可以用acquire動態地新增permits的數量,它表示的是一次性獲取許可的數量,比如:
public class Driver {
// 訊號量共10個
private Semaphore semaphore = new Semaphore(10);
public void driveCar() {
try {
// 每次獲取3個
semaphore.acquire(3);
System.out.println(Thread.currentThread().getName() + " start at " + System.currentTimeMillis());
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + " stop at " + System.currentTimeMillis());
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
在上述程式碼中總的訊號量除以每次獲取的許可數即10/3=3,就是說可以允許3個執行緒一起執行。
我們可以用public int availablePermits()
檢視現在可用的訊號量:
public class SemaphoreAvaliablePermits {
public static void main(String[] args) {
try{
Semaphore semaphore = new Semaphore(10);
System.out.println("Semaphore available permits: " + semaphore.availablePermits());
semaphore.acquire();
System.out.println("Semaphore available permits: " + semaphore.availablePermits());
semaphore.acquire(2);
System.out.println("Semaphore available permits: " + semaphore.availablePermits());
semaphore.acquire(3);
System.out.println("Semaphore available permits: " + semaphore.availablePermits());
semaphore.acquire(4);
System.out.println("Semaphore available permits: " + semaphore.availablePermits());
semaphore.release();
System.out.println("Semaphore available permits: " + semaphore.availablePermits());
semaphore.release(2);
System.out.println("Semaphore available permits: " + semaphore.availablePermits());
semaphore.release(3);
System.out.println("Semaphore available permits: " + semaphore.availablePermits());
semaphore.release(4);
System.out.println("Semaphore available permits: " + semaphore.availablePermits());
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
輸出:
Semaphore available permits: 10
Semaphore available permits: 9
Semaphore available permits: 7
Semaphore available permits: 4
Semaphore available permits: 0
Semaphore available permits: 1
Semaphore available permits: 3
Semaphore available permits: 6
Semaphore available permits: 10
還有一個方法public int drainPermits()
,這個方法返回即可所有的許可數目,並將許可置0:
public class SemaphoreDrainPermits {
public static void main(String[] args) {
try{
Semaphore semaphore = new Semaphore(10);
System.out.println("Semaphore available permits: " + semaphore.availablePermits());
semaphore.acquire();
System.out.println("Semaphore available permits: " + semaphore.availablePermits());
System.out.println("Semaphore drain permits" + semaphore.drainPermits());
System.out.println("Semaphore available permits: " + semaphore.availablePermits());
System.out.println("Semaphore drain permits" + semaphore.drainPermits());
System.out.println("Semaphore available permits: " + semaphore.availablePermits());
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
輸出:
Semaphore available permits: 10
Semaphore available permits: 9
Semaphore drain permits9
Semaphore available permits: 0
Semaphore drain permits0
Semaphore available permits: 0
相關推薦
java併發程式設計之Semaphore(訊號量)的用法
Semaphore類其實就是synchronized關鍵字的升級版,這個類主要作用就是控制執行緒併發的數量,而在這方面synchronized就有點力不足了,接下來我們就開始先了解一下Semaphore的一些常用方法就注意細節。 在new 這個類的時候需要給這個類傳遞一個引
android 驅動中的併發和競爭——semaphore(訊號量)
在現代的Linux系統中,有非常多的併發源,因此而帶來競爭情況,競爭來源於不同的程序對同一共享資源的同時存取。而Linux系統提供了一系列的處理併發和資源競爭的方法,下面介紹幾個: 1、semaphore(訊號量) 訊號量的使用類似於一對P、V函式,通常一個想進入臨界區的程
JAVA併發程式設計——Semaphore(訊號量)
控制併發執行緒數的Semaphore Semaphore(訊號量)是用來控制同時訪問特定資源的執行緒數量,它通過協調各個執行緒,以保證合理的使用公共資源。應用場景Semaphore可以用於做流量控制,特別是公用資源有限的應用場景,比如資料庫連線。假如有一個需求,
Java併發程式設計之Semaphore(二)
一.介紹 Semaphore是一種在多執行緒環境下使用的設施,該設施負責協調各個執行緒,以保證它們能夠正確、合理的使用公共資源的設施,也是作業系統中用於控制程序同步互斥的量。Semaphore是一種計數訊號量,用於管理一組資源,內部是基於AQS的共享模式。它相當於給執行緒規定一個量從而控制允
併發:控制併發執行緒數的Semaphore(訊號量)。
Semaphore是用來控制同時訪問特定資源的執行緒數量,他通過協調各個執行緒,以保證合理的使用公平資源。 多年以來,我都覺得從字面上很難理解Semaphore所表達的含義,只能把他比作是控制流量的紅綠燈。比如xx馬路要限制流量,只允許同時有一百兩車在這條路上行使,其他的都必須在路口等待,所以前
Java併發包之閉鎖/柵欄/訊號量及併發模型和鎖
threadLocal能夠為每一個執行緒維護變數副本,常用於在多執行緒中用空間換時間 程序死鎖:程序死鎖,指多個程序迴圈等待他方佔有的資源而一直等待下去的局面; 程序活鎖:執行緒1,2需要同時佔有a,b才可以,1佔有a,2佔有b,為了避免死鎖,
Java併發包之閉鎖/柵欄/訊號量
一、Java多執行緒總結: 描述執行緒的類:Runable和Thread都屬於java.lang包。 內建鎖synchronized屬於jvm關鍵字,內建條件佇列操作介面Object.wait()/
Java 併發程式設計 之 volatile(三)
都是快取惹的禍害 快取一致性協議: 當某個CPU核心寫資料時,如果發現這個變數為共享變數,即在其他CPU快取中也有副本,就會通知其他CPU將改變數的快取置為無效, 其他CPU需要從記憶體重新讀取。 MESI 的狀態 案例: 資料有
程序(三):程序同步——Lock(鎖)、Semaphore(訊號量)、Event(事件)
目錄 鎖 —— multiprocess.Lock 訊號量 —— multiprocess.Semaphore(瞭解) 事件 —— multiprocess.Event(瞭解) 鎖 —— multiprocess.Lock 當多個程序使用同一份資料資源的時候,就會引發資料
執行緒(三):Lock(互斥鎖)、RLock( 遞迴鎖)、Semaphore(訊號量)、Event(事件)、Condition(條件)、Timer(定時器)、queue(佇列)
目錄 一、鎖 1)同步鎖 2)死鎖與遞迴鎖 二、訊號量 三、事件 四、條件 五、定時器 六、執行緒佇列 一、鎖 1)同步鎖 #同步鎖的引用 from threading import Thread,Lock import os,time def wor
c# Semaphore(訊號量)
http://www.cnblogs.com/tianzhiliang/archive/2010/08/31/1813635.html http://hi.baidu.com/bloodcrystal/blog/item/00ebd7f9da5aadd2b58f317c.h
JUC 中提供的限流利器-Semaphore(訊號量)
在 JUC 包下,有一個 Semaphore 類,翻譯成訊號量,Semaphore(訊號量)是用來控制同時訪問特定資源的執行緒數量,它通過協調各個執行緒,以保證合理的使用公共資源。Semaphore 跟鎖(synchronized、Lock)有點相似,不同的地方是,鎖同一時刻只允許一個執行緒訪問某一資源,而
java架構之路(多執行緒)JUC併發程式設計之Semaphore訊號量、CountDownLatch、CyclicBarrier柵欄、Executors執行緒池
上期回顧: 上次部落格我們主要說了我們juc併發包下面的ReetrantLock的一些簡單使用和底層的原理,是如何實現公平鎖、非公平鎖的。內部的雙向連結串列到底是什麼意思,prev和next到底是什麼,為什麼要引入heap和tail來值向null的Node節點。高併發時候是如何保證state來記錄重入鎖的
Java併發程式設計(8)-Semaphore訊號量解讀
文章目錄 一、Semaphore訊號量 1.1、什麼是訊號量 1.2、訊號量在併發程式設計中的作用 二、Semaphore類簡單解讀 2.1、構造方法解讀
Java併發程式設計實戰————Semaphore訊號量的使用淺析
引言 本篇部落格講解《Java併發程式設計實戰》中的同步工具類:訊號量 的使用和理解。 從概念、含義入手,突出重點,配以程式碼例項及講解,並以生活中的案例做類比加強記憶。 什麼是訊號量 Java中的同步工具類訊號量即計數訊號量(Counting Semaphore),是
Java併發程式設計之鎖機制之(ReentrantLock)重入鎖
最近在忙公司的專案,現在終於有時間來寫部落格啦~開心開心 前言 通過前面的文章,我們已經瞭解了AQS(AbstractQueuedSynchronizer)內部的實現與基本原理。現在我們來了解一下,Java中為我們提供的Lock機制下的鎖實現--ReentrantLock(重入鎖),閱讀該篇文章
Java併發程式設計之鎖機制之ReentrantReadWriteLock(讀寫鎖)
前言 在前面的文章中,我們講到了ReentrantLock(重入鎖),接下來我們講ReentrantReadWriteLock(讀寫鎖),該鎖具備重入鎖的可重入性、可中斷獲取鎖等特徵,但是與ReentrantLock不一樣的是,在ReentrantReadWriteLock中,維護了一對鎖,一個讀鎖一個寫鎖
Java併發程式設計之CountDownLatch、CyclicBarrier和Semaphore
在java 1.5中,提供了一些非常有用的輔助類來幫助我們進行併發程式設計,比如CountDownLatch,CyclicBarrier和Semaphore,今天我們就來學習一下這三個輔助類的用法。 CountDownLatch CountDownLa
java 併發程式設計學習筆記(一)之 併發基礎
併發基礎 併發小測試 java.util.concurrent.Semaphore 類 public class SemTest { /** * Se
java 併發程式設計學習筆記(一)之 基礎框架搭建和併發模擬工具,程式碼
基礎框架搭建和併發模擬工具,程式碼 (1)基礎框架搭建 (2)併發模擬 (3)CountDownLatch 通常用來 保證 幾個執行緒執行完成之後,再執行其他的程式碼 Semaphore