java多线程-Semaphore
一、Semaphore
Semaphore既可以实现限制访问有限资源的线程数量,同时也可以实现线程之间的同步;Semaphore的使用场景可以在数据库连接池中使用,一个数据库往往会有连接数量的限制,一个数据库的连接数量就是有限的资源,而使用信号量就可以限制线程连接数据库的数量;
- 方法
//构造方法
Semaphore(int num);//num=1实现线程的同步,num>1时为计数信号量实现有限资源管理,
Semaphore(int num,boolean fair);//fair为true表示公平的方式获取信号量,false为非公平的方式
//获取和释放信号量方法
acquire():获取信号量
release():释放信号量
tryAcquire():尝试获取信号量,如何获取成功返回true,失败返回false
二、Semaphore实例
package java_lang_Object;
import java.util.concurrent.Semaphore;
/**
* Created by luckyboy on 2018/7/10.
*/
public class SemaphoreTest {
public static void main(String[] args){
Semaphore semaphore = new Semaphore(3);
for(int i = 0;i<9;i++){
MyThread7_15 thread = new MyThread7_15(semaphore);
thread.start();
}
}
}
class MyThread7_15 extends Thread{
private Semaphore semaphore;
public MyThread7_15(Semaphore semaphore){
this.semaphore = semaphore;
}
@Override
public void run(){
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName()+"在某个时刻"+System.currentTimeMillis()+" 进入临界区");
Thread.sleep(3000);
System.out.println(Thread.currentThread().getName()+"在某个时刻"+System.currentTimeMillis()+" 退出临界区");
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
输出结果
Thread-0在某个时刻1531208183254 进入临界区
Thread-1在某个时刻1531208183254 进入临界区
Thread-2在某个时刻1531208183254 进入临界区
Thread-1在某个时刻1531208186254 退出临界区
Thread-0在某个时刻1531208186254 退出临界区
Thread-3在某个时刻1531208186254 进入临界区
Thread-4在某个时刻1531208186254 进入临界区
Thread-2在某个时刻1531208186255 退出临界区
Thread-5在某个时刻1531208186255 进入临界区
Thread-4在某个时刻1531208189255 退出临界区
Thread-3在某个时刻1531208189255 退出临界区
Thread-6在某个时刻1531208189255 进入临界区
Thread-7在某个时刻1531208189255 进入临界区
Thread-5在某个时刻1531208189256 退出临界区
Thread-8在某个时刻1531208189256 进入临界区
Thread-6在某个时刻1531208192255 退出临界区
Thread-7在某个时刻1531208192255 退出临界区
Thread-8在某个时刻1531208192256 退出临界区
结果分析
- 我们可以看到在一开始只有Thread0、1、2进入了临界区,当Thread0、Thread1退出了临界区以后,Thread3、Thread4马上进入了临界区;也就是临界区永远保证只有在Semaphore允许的线程数下,进入线程进行资源共享;
- 这里我们要清楚的是Semaphore只是限制线程进入某一临界资源的数量,并没有保证已经进入临界资源的线程之间是同步的。
- 从上面的测试来看,Semaphore适合用于限制访问某一资源池的线程的数量;像数据库的连接池(其实我很好奇线程池使用的是队列,那么我们需要使用Semaphore吗??)
Semaphore源码
参考文章
http://www.cnblogs.com/xrq730/p/4869671.html
https://www.cnblogs.com/uodut/p/6830939.html