信號量---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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...