Java线程之信号灯的使用

信号灯类Semaphore:

一个计数信号量,通常用于限制可以访问某些资源(物理或逻辑的)的线程数目。

单个信号量可以实现互斥锁的功能并且可以是由一个线程获得了锁,再由另一个线程释放,

此时只允许一个线程进去访问某些资源。该类对象可以维护当前访问自身的线程的个数,

并提供了同步的机制,它控制同时访问资源的线程个数,例如实现一个同时访问文件的并发访问。

打个不恰当的例子:之前学的线程同步与互斥相当于我们去洗手,但是只有一个水龙头,很多人

都在等,当一个人获得洗手的资格,其他人就不能去洗,只有等到这个人洗完了,释放了水龙头

其他等的人才能洗。而信号灯就相当于,这里有3个水龙头,但是依然是很多人在排队洗手,只有

当在洗手的三个人中有人洗完了,释放了水龙头,其余等的人才能去洗,这样一次就是有三个人同时洗手。

示例:

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

/*
 * 创建一个缓存线程池,当向线程池丢入10个任务的时候,缓存线程池会生成10个线程去执行这10个任务,
 * 然后创建一个信号量对象,一次只允许3个线程同时访问资源,只有当三个线程中的某一个释放了信号灯,
 * 其他7个等待的线程才有机会执行,当然要看谁拿到该信号灯。
 */
public class SempaphoreTest {

	public static void main(String[] args) {
		//创建一个缓存线程池
		ExecutorService pools = Executors.newCachedThreadPool();
		//创建具有给定的许可数和给定的公平设置的 Semaphore
		final Semaphore sp = new Semaphore(3,true);
		//向线程池中扔10个任务
		for(int i=0;i<10;i++) {
			Runnable runnable = new Runnable() {
				
				@Override
				public void run() {
					//上锁
					try {
						sp.acquire();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println("线程" + Thread.currentThread().getName() + "进入,当前有" + 
					(3-sp.availablePermits()) + "个并发");
					try {
						Thread.sleep((long)(Math.random()*10000));
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println("线程" + Thread.currentThread().getName() + "即将离开");
					sp.release();//释放信号灯
					System.out.println("线程" + Thread.currentThread().getName() + "已经离开,当前有" + 
					(3-sp.availablePermits()) + "个并发");
				}
			};
			pools.execute(runnable);
		}
	}
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值