一、信号量的概念
信号量在多个共享资源互斥时使用,控制最大线程数。信号量是对锁的拓展,互斥锁每次都只允许一个线程访问一个资源,而信号量可以指定多个线程同时访问一个资源。例如银行窗口服务
二、信号量的使用
2.1 信号量的常用方法
// 尝试获得一个准入的许可。若无法获得,则线程会等待,直到有线程释放一个许可或者当前线程被中断。
public void acquire()
// 与 acquire()基本相同,区别是其不响应中断。
public void acquireUninterruptibly()
// 尝试获得一个许可,如果成功返回true,失败则返回false,其不会进行等待,立即返回。
public boolean tryAcquire()
// 与 tryAcquire()基本相同,区别是其增加尝试的时间和时间单位。
public boolean tryAcquire(long timeout, TimeUnit unit)
// 用于在线程访问资源结束后,释放一个许可,以使其他等待许可的线程可以进行资源访问。
public void release()
2.2 信号量的使用
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(2);
for(int i=0;i<5;i++){
new Thread(()->{
try {
semaphore.acquire();//上厕所
System.out.println(Thread.currentThread().getName() + "开始上厕所");
TimeUnit.SECONDS.sleep(3);// 三秒小手
System.out.println(Thread.currentThread().getName() + "上完厕所");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
semaphore.release();//离开厕所
}
},String.valueOf(i)).start();
}
}
执行结果
0开始上厕所
1开始上厕所
0上完厕所
1上完厕所
4开始上厕所
2开始上厕所
4上完厕所
2上完厕所
3开始上厕所
3上完厕所
进程已结束,退出代码0
三、总结
Semaphore类似ReentrantLock可以指定公平性,并且在高并发的使用场景更广泛,类似资源池。
一般常用非公平的信号量,非公平信号量是指在获取许可时先尝试获取许可,而不必关心是否已有需要获取许可的线程位于等待队列中,如果获取失败,才会入列。而公平的信号量在获取许可时首先要查看等待队列中是否已有线程,如果有则入列。
公平信号量的创建方式: Semaphore semaphore = new Semaphore(2,true);
可以结合java多线程该文一起学习。