信號量---Java Semaphore類詳解說明

来源:https://www.cnblogs.com/java265/archive/2022/04/29/16205276.html
-Advertisement-
Play Games

適用 2022.1 【更新時間 2022-4-29】 引言 由於IDEA在2021.2.2以後我們不能再使用重置大法白嫖了。 為了打擊破解,Jetbrains煞費苦心,這次採用了JB賬號登陸,通過授權認證獲取免費試用資格(所以之前的無限重置的插件在今後的新版本中,將無法使用),以下整理了一個免JB註 ...


轉自:

http://www.java265.com/JavaCourse/202204/3184.html

 

下文筆者講述java中Semaphore類的詳解說明,如下所示:

Semaphore簡介

Semaphore(中文翻譯:信號量)
   我們常用於控制訪問某一資源的線程個數,
   使用這種方式可使大家按照一定的規則訪問某一資源 
Semaphore的原理:
     通過使用計數器來控制對某一資源的訪問
	  當計數器大於0,則允許訪問
      當計數器為0時,則拒絕訪問
      計數器中的計數作為允許訪問共用資源的許可
即:訪問資源,需從信號量中授予線程許可

Semaphore方法

方法名 備註
void acquire() 從信號量獲取一個許可,在無可用許可前,將一直阻塞等待
void acquire(int permits) 獲取指定數目的許可,在無可用許可前,也將會一直阻塞等待
boolean tryAcquire() 從信號量嘗試獲取一個許可,當無可用許可,直接返回false,不會阻塞
boolean tryAcquire(int permits) 嘗試獲取指定數目的許可,當無可用許可直接返回false
boolean tryAcquire(int permits, long timeout, TimeUnit unit) 在指定的時間內嘗試從信號量中獲取許可,當在指定的時間內獲取成功,返回true,否則返回false
void release() 釋放一個許可,別忘了在finally中使用
註意:多次調用該方法,會使信號量的許可數增加,達到動態擴展的效果
如:初始permits為1,調用了兩次release,最大許可會改變為2
int availablePermits() 獲取當前信號量可用的許可

Semaphore構造函數

 public Semaphore(int permits) {
        sync = new NonfairSync(permits);
    }

public Semaphore(int permits, boolean fair) {
        sync = fair ? new FairSync(permits) : new NonfairSync(permits);
    }
參數說明:
     permits:初始許可數,即最大訪問線程數
     fair:當設置為false時,創建的信號量為非公平鎖;當設置為true時,信號量是公平鎖

使用Semaphore限制登錄的最大用戶數

package com.java265.other;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
public class Test16 {
	public static void main(String[] args) {
		// 允許最大的獲取用戶的線程數
		int slots = 8;
		ExecutorService executorService = Executors.newFixedThreadPool(slots);
		UserUsingSemaphore loginQueue = new UserUsingSemaphore(slots);
		// 線程池模擬登錄
		for (int i = 1; i <= slots; i++) {
			final int num = i;
			executorService.execute(() -> {
				if (loginQueue.tryAcquire()) {
					System.out.println("用戶:" + num + "獲取成功!");
				} else {
					System.out.println("用戶:" + num + "獲取失敗!");
				}
			});
		}
		executorService.shutdown();

		System.out.println("當前可用許可證數:" + loginQueue.availableSlots());

		// 此時已經有8個線程,再次獲取的時候會返回false
		if (loginQueue.tryAcquire()) {
			System.out.println("獲取成功!");
		} else {
			System.out.println("資源已經被占滿,獲取失敗!");
		}
		// 有用戶釋放資源,只釋放一個資源
		loginQueue.releaseAcquire();

		// 再次獲取
		if (loginQueue.tryAcquire()) {
			System.out.println("獲取成功-2!");
		} else {
			System.out.println("資源已經被占滿,獲取失敗-2!");
		}

		// 再次獲取-會失敗,因為又沒有空餘
		if (loginQueue.tryAcquire()) {
			System.out.println("獲取成功-3!");
		} else {
			System.out.println("資源已經被占滿,獲取失敗-3!");
		}
	}
}


/*
 * 定義一個登錄隊列,用於獲取信號量
 */
class UserUsingSemaphore {

	private Semaphore semaphore;

	/**
	 * @param 設置信號量的大小
	 */
	public UserUsingSemaphore(int slotLimit) {
		semaphore = new Semaphore(slotLimit);
	}

	boolean tryAcquire() {
		// 獲取一個憑證
		return semaphore.tryAcquire();
	}

	/*
	 * 釋放憑證
	 */
	void releaseAcquire() {
		semaphore.release();
	}

	/*
	 * 獲取可用的憑證數量
	 */
	int availableSlots() {
		return semaphore.availablePermits();
	}
}

------運行以上代碼,將輸出以下信息------
用戶:1獲取成功!
用戶:5獲取成功!
用戶:2獲取成功!
用戶:4獲取成功!
用戶:3獲取成功!
用戶:7獲取成功!
用戶:6獲取成功!
當前可用許可證數:1
資源已經被占滿,獲取失敗!
獲取成功-2!
資源已經被占滿,獲取失敗-3!
用戶:8獲取成功!

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 作者 Atzuge 鏈接 https://www.cnblogs.com/zuge/p/7397255.html DataGrip是大名鼎鼎的JetBrains公司出品的,就是那個出品Intellij IDEA的公司。它是一款資料庫管理客戶端工具,方便連接到資料庫伺服器,執行sql、創建表、創建索引 ...
  • 前言 在使用Python的過程中,我最喜歡的就是Python的各種第三方庫,能夠完成很多操作。 下麵就給大家介紹5個通過Python構建的項目,以此來學習Python編程。 一、石頭剪刀布游戲 目標:創建一個命令行游戲,游戲者可以在石頭、剪刀和布之間進行選擇,與電腦PK。如果游戲者贏了,得分就會添 ...
  • 封裝:隱藏內部功能的具體實現,只保留和外部交流數據的介面。繼承:一個對象可以從它的父類繼承所有的通用的屬性和方法,併在無需重新編寫原來的類的情況下對這些功能進行擴展;最大的好處是實現代碼的高效重用。多態:同一個動作作用於不同的對象 所產生不同的行為。 ...
  • 在這次的Java 18中,新增了一個@snipppet標簽,主要用於JavaDoc中需要放示例代碼的場景。其實在Java 18之前,已經有一個@code標簽,可以用於在JavaDoc中編寫小段的代碼內容,比如在之前介紹Simple Web Server視頻中,提到的這段樣例代碼,就是用@code標簽 ...
  • 最近正在學習回溯法,遇到的第一個問題就是n皇後問題,問題如下: 要求在一個n×n的棋盤上放置n個皇後,使得任意兩個皇後不在同一行或同一列或同一斜線上。 直接上代碼: #include<iostream> #include<math.h> using namespace std; void NQuee ...
  • POM :文件名稱是pom.xml ,  pom翻譯過來叫做項目對象模型,maven把一個項目當做一個模型使用 ...
  • 背景介紹 R和Python作為兩個開源、且容易上手的數據分析和繪圖工具,在科研中應用的比較廣泛。 在接下來的日子,我們圍繞Python進行繪圖和數據分析話題,寫一系列推文,事實上是我自己的一些學習筆記分享出來,為了我 方便查閱,也方便大家翻閱。 軟體介紹 [軟體名稱]:Anaconda | Spyd ...
  • 我們知道,頻繁操作資料庫會降低伺服器的系統性能,因此通常需要將頻繁訪問、更新的數據存入到緩存。Halo 項目也引入了緩存機制,且設置了多種實現方式,如自定義緩存、Redis、LevelDB 等,下麵我們分析一下緩存機制的實現過程。 ...
一周排行
    -Advertisement-
    Play Games
  • GoF之工廠模式 @目錄GoF之工廠模式每博一文案1. 簡單說明“23種設計模式”1.2 介紹工廠模式的三種形態1.3 簡單工廠模式(靜態工廠模式)1.3.1 簡單工廠模式的優缺點:1.4 工廠方法模式1.4.1 工廠方法模式的優缺點:1.5 抽象工廠模式1.6 抽象工廠模式的優缺點:2. 總結:3 ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 本章將和大家分享ES的數據同步方案和ES集群相關知識。廢話不多說,下麵我們直接進入主題。 一、ES數據同步 1、數據同步問題 Elasticsearch中的酒店數據來自於mysql資料庫,因此mysql數據發生改變時,Elasticsearch也必須跟著改變,這個就是Elasticsearch與my ...
  • 引言 在我們之前的文章中介紹過使用Bogus生成模擬測試數據,今天來講解一下功能更加強大自動生成測試數據的工具的庫"AutoFixture"。 什麼是AutoFixture? AutoFixture 是一個針對 .NET 的開源庫,旨在最大程度地減少單元測試中的“安排(Arrange)”階段,以提高 ...
  • 經過前面幾個部分學習,相信學過的同學已經能夠掌握 .NET Emit 這種中間語言,並能使得它來編寫一些應用,以提高程式的性能。隨著 IL 指令篇的結束,本系列也已經接近尾聲,在這接近結束的最後,會提供幾個可供直接使用的示例,以供大伙分析或使用在項目中。 ...
  • 當從不同來源導入Excel數據時,可能存在重覆的記錄。為了確保數據的準確性,通常需要刪除這些重覆的行。手動查找並刪除可能會非常耗費時間,而通過編程腳本則可以實現在短時間內處理大量數據。本文將提供一個使用C# 快速查找並刪除Excel重覆項的免費解決方案。 以下是實現步驟: 1. 首先安裝免費.NET ...
  • C++ 異常處理 C++ 異常處理機制允許程式在運行時處理錯誤或意外情況。它提供了捕獲和處理錯誤的一種結構化方式,使程式更加健壯和可靠。 異常處理的基本概念: 異常: 程式在運行時發生的錯誤或意外情況。 拋出異常: 使用 throw 關鍵字將異常傳遞給調用堆棧。 捕獲異常: 使用 try-catch ...
  • 優秀且經驗豐富的Java開發人員的特征之一是對API的廣泛瞭解,包括JDK和第三方庫。 我花了很多時間來學習API,尤其是在閱讀了Effective Java 3rd Edition之後 ,Joshua Bloch建議在Java 3rd Edition中使用現有的API進行開發,而不是為常見的東西編 ...
  • 框架 · 使用laravel框架,原因:tp的框架路由和orm沒有laravel好用 · 使用強制路由,方便介面多時,分多版本,分文件夾等操作 介面 · 介面開發註意欄位類型,欄位是int,查詢成功失敗都要返回int(對接java等強類型語言方便) · 查詢介面用GET、其他用POST 代碼 · 所 ...
  • 正文 下午找企業的人去鎮上做貸後。 車上聽同事跟那個司機對罵,火星子都快出來了。司機跟那同事更熟一些,連我在內一共就三個人,同事那一手指桑罵槐給我都聽愣了。司機也是老社會人了,馬上聽出來了,為那個無辜的企業經辦人辯護,實際上是為自己辯護。 “這個事情你不能怪企業。”“但他們總不能讓銀行的人全權負責, ...