ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java Semaphore类详解说明

2022-07-12 16:35:33  阅读:185  来源: 互联网

标签:Java 许可 permits int 信号量 获取 详解 Semaphore


转自:

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获取成功!

标签:Java,许可,permits,int,信号量,获取,详解,Semaphore
来源: https://www.cnblogs.com/java265/p/16467301.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有