java并发之同步辅助类(Semphore、CountDownLatch、CyclicBarrier、Phaser、Exchanger)

1、Semphore

字面翻译的意思是(信号量)。正常的锁来自(concurrent.lock或内建的synchronized锁),在任何时刻都只允许一个任务访问同一资源,而技术信号量允许n个任务同时访问这个资源。你还可以就信号量看成是在向外分发资源的"许可证",尽管实际上没有用到人任何的许可证对象。

信号量就是允许声明多把锁(含一把锁,此时为互斥信号量)。

实现原理:Semaphore是信号量,用于管理一组资源。其内部是基于AQS的共享模式,AQS的状态表示许可证的数量,在许可证数量不够时,线程将会被挂起;而一旦有一个线程释放一个资源,那么就有可能重新唤醒等待队列中的线程继续执行。

举例:比如参观中山陵,人比较多每次只能放一批人进去,没有准许进去的只能在外面等,等有一批人出来了再放进去一批。

package com.soecode.lyf.web.test;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Semaphore;

public class SemaphoreTest {
	public static void main(String[] args) {

		//打印Semaphore的所有的方法
		//acquire():获取信号量,信号量内部计数器减1
		//release():释放信号量,信号量内部计数器加1
		//tryAcquire():这个方法试图获取信号量,如果能够获取返回true,否则返回false
		Method[] method = Semaphore.class.getDeclaredMethods();
		System.out.println("打印Semaphore所有的方法:");
		for(Method m : method){
			System.out.println(m.getName());
		}

		//每次只能容纳4人进入
		Semaphore s=new Semaphore(4);
		//初始化中山陵风景区
		VisitorSunMausoleum vm = new VisitorSunMausoleum(s);
		//定义一群游客
		List<VisitorStart> list = new ArrayList<VisitorStart>();
		for(int i=0;i<100;i++){
			list.add(new VisitorStart(vm));
		}
		//开始组团参观
		int i=0;
		for(VisitorStart v : list){
			System.out.println(i++);
			v.run();
		}

	}


}
//参观中山陵风景区
class VisitorSunMausoleum{

	private Semaphore semaphore;

	public VisitorSunMausoleum(Semaphore semaphore){
		this.semaphore = semaphore;
	}

	public void visitStart() {
		try {
			System.out.println("前");
			//一旦超过访问限制就会在此处拦截
			semaphore.acquire();
			/*boolean b = semaphore.tryAcquire();
			System.out.println(b);*/
			System.out.println("后");
			System.out.println("参观开始=====");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public void visitEnd() {
		try {
			semaphore.release();
			System.out.println("参观结束*****");

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

//游客
class VisitorStart implements Runnable{

	private VisitorSunMausoleum sun;

	public VisitorStart(VisitorSunMausoleum sun){
		this.sun=sun;
	}


	@Override
	public void run() {
		try {
			sun.visitStart();
			Thread.sleep(1000);
			//sun.visitEnd();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}


}

打印的日志:

打印Semaphore所有的方法:
acquire
acquire
tryAcquire
tryAcquire
tryAcquire
tryAcquire
toString
getQueueLength
getQueuedThreads
hasQueuedThreads
isFair
release
release
acquireUninterruptibly
acquireUninterruptibly
availablePermits
drainPermits
reducePermits
0
前
后
参观开始=====
1
前
后
参观开始=====
2
前
后
参观开始=====
3
前
后
参观开始=====
4
前

当第四个打印出"后",便不再继续执行了。将//visitEnd();这一行释放掉可以看到日志如下:

打印Semaphore所有的方法:
toString
getQueueLength
getQueuedThreads
hasQueuedThreads
isFair
release
release
acquire
acquire
tryAcquire
tryAcquire
tryAcquire
tryAcquire
acquireUninterruptibly
acquireUninterruptibly
availablePermits
drainPermits
reducePermits
0
前
后
参观开始==
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值