Semaphore学习笔记

本文详细介绍了计数信号量Semaphore的概念与使用方法,包括主要API解析及代码示例。Semaphore用于控制同时访问特定资源的线程数量,通过协调各个线程避免资源争抢。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

官方解释:

一个计数信号量。从概念上讲,信号量维护了一个许可集。如有必要,在许可可用前会阻塞每一个 acquire(),然后再获取该许可。每个 release() 添加一个许可,从而可能释放一个正在阻塞的获取者。但是,不使用实际的许可对象,Semaphore 只对可用许可的号码进行计数,并采取相应的行动。


使用场景:

Semaphore 通常用于限制可以访问某些资源(物理或逻辑的)的线程数目。


主要方法:

void	acquire() 
          从此信号量获取一个许可,在提供一个许可前一直将线程阻塞,否则线程被中断。
 void	acquire(int permits) 
          从此信号量获取给定数目的许可,在提供这些许可前一直将线程阻塞,或者线程已被中断。
 void	acquireUninterruptibly() 
          从此信号量中获取许可,在有可用的许可前将其阻塞。
 void	acquireUninterruptibly(int permits) 
          从此信号量获取给定数目的许可,在提供这些许可前一直将线程阻塞。
 int	availablePermits() 
          返回此信号量中当前可用的许可数。
 int	drainPermits() 
          获取并返回立即可用的所有许可。
protected  Collection<Thread>	getQueuedThreads() 
          返回一个 collection,包含可能等待获取的线程。
 int	getQueueLength() 
          返回正在等待获取的线程的估计数目。
 boolean	hasQueuedThreads() 
          查询是否有线程正在等待获取。
 boolean	isFair() 
          如果此信号量的公平设置为 true,则返回 true。
protected  void	reducePermits(int reduction) 
          根据指定的缩减量减小可用许可的数目。
 void	release() 
          释放一个许可,将其返回给信号量。
 void	release(int permits) 
          释放给定数目的许可,将其返回到信号量。
 String	toString() 
          返回标识此信号量的字符串,以及信号量的状态。
 boolean	tryAcquire() 
          仅在调用时此信号量存在一个可用许可,才从信号量获取许可。
 boolean	tryAcquire(int permits) 
          仅在调用时此信号量中有给定数目的许可时,才从此信号量中获取这些许可。
 boolean	tryAcquire(int permits, long timeout, TimeUnit unit) 
          如果在给定的等待时间内此信号量有可用的所有许可,并且当前线程未被中断,则从此信号量获取给定数目的许可。
 boolean	tryAcquire(long timeout, TimeUnit unit) 
          如果在给定的等待时间内,此信号量有可用的许可并且当前线程未被中断,则从此信号量获取一个许可。


代码实例:

这里是一个实际的情况,大家排队上厕所,厕所只有两个位置,来了10个人需要排队。

代码:

package com.bennytian.test;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;


/**
 * @author BennyTian
 * @date 2015年9月14日 上午10:31:55
 */
public class MySemaphore implements Runnable{

	private int id;
	private Semaphore semaphore ;
	
	public MySemaphore(int id,Semaphore semaphore) {
		this.id = id;
		this.semaphore = semaphore;
	}
	
	@Override
	public void run() {
		
		try {
			
			if(semaphore.availablePermits() > 0){
				System.out.println("顾客"+this.id+"已进入厕所,坑位可用." + System.currentTimeMillis());
			}else{
				System.out.println("顾客"+this.id+"已进入厕所,坑位已用完,等待坑位中..." + System.currentTimeMillis());
			}
			
			this.semaphore.acquire();
			
			System.out.println("顾客"+this.id+"准备就绪,开始如厕." + System.currentTimeMillis());
			Thread.sleep((int)(Math.random() * 5000));
			
			System.out.println("顾客"+this.id+"如厕完毕,腾出坑位." + System.currentTimeMillis());
			this.semaphore.release();
			
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		
		int wcCount = 2;
		int customerCount = 10;
		
		Semaphore semaphore = new Semaphore(wcCount);
		
		ExecutorService service = Executors.newCachedThreadPool();
		
		for (int i = 0; i < customerCount; i++) {
			service.execute(new MySemaphore(i, semaphore));
		}
		
		service.shutdown();
	}

}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值