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
前
后
参观开始==