关于Semaphore的使用介绍
关于Semaphore的使用介绍1.什么是SemaphoreSemaphore是一个计数信号量,通常用于限制对某些资源访问的线程数量,Semaphore管理一系列许可证。举个栗子:假如我们要去游泳池游泳,泳池一共有6条泳道,每条泳道只能有1个人在上面使用。每个人去游泳之前要先 acquire() 一下获取许可证,如果有空闲泳道就可以去游泳;如果没有空闲泳道,就只能阻塞等待。游完泳之后,再 ...
·
关于Semaphore的使用介绍
1.什么是Semaphore
Semaphore是一个计数信号量,通常用于限制对某些资源访问的线程数量,Semaphore管理一系列许可证。举个栗子:
- 假如我们要去游泳池游泳,泳池一共有6条泳道,每条泳道只能有1个人在上面使用。每个人去游泳之前要先 acquire() 一下获取许可证,如果有空闲泳道就可以去游泳;如果没有空闲泳道,就只能阻塞等待。游完泳之后,再 release() 一下释放许可证,释放出该泳道的使用权,确保下一个人 acquire() 的时候可以获取可用泳道,继续游泳。如果泳道上都有人了,再有人过来游泳,就需要等待其他人。
- 这个泳道的数量,我们是可以自行设定的。这里的泳池就是共享资源,而泳道的数量就是可访问的线程数量,游泳者就是线程。
2.Semaphore的简单使用
public class SemaphoreTest {
public static void main(String[] args) {
//创建一个可缓存的线程池
ExecutorService executor = Executors.newCachedThreadPool();
//信号量
Semaphore semaphore = new Semaphore(6);
System.out.println("初始化: 当前有" + semaphore.availablePermits() + "个泳道可用");
//创建10个任务(相当于10个游泳者)
for (int i = 0; i < 10; i++) {
//记录第几个任务(相当于第几个游泳者)
final int No = i;
executor.execute(() -> {
try {
semaphore.acquire(); //获取许可
System.out.println(Thread.currentThread().getName() + "游泳者" + No + "获取了许可(获取了泳道)," + "还剩"
+ semaphore.availablePermits() + "个泳道可用~");
//执行耗时操作(相当于正在游泳)
Thread.sleep(1000);
semaphore.release(); //释放许可
System.out.println(Thread.currentThread().getName() + "游泳者" + No + "释放了许可(离开了泳道)," + "还剩"
+ semaphore.availablePermits() + "个泳道可用~");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
//关闭线程池
executor.shutdown();
}
}
打印结果之一,每次运行都可能不一样:
初始化: 当前有6个泳道可用
pool-1-thread-1游泳者0获取了许可(获取了泳道),还剩5个泳道可用~
pool-1-thread-2游泳者1获取了许可(获取了泳道),还剩4个泳道可用~
pool-1-thread-3游泳者2获取了许可(获取了泳道),还剩3个泳道可用~
pool-1-thread-4游泳者3获取了许可(获取了泳道),还剩2个泳道可用~
pool-1-thread-5游泳者4获取了许可(获取了泳道),还剩1个泳道可用~
pool-1-thread-6游泳者5获取了许可(获取了泳道),还剩0个泳道可用~
pool-1-thread-7游泳者6获取了许可(获取了泳道),还剩0个泳道可用~
pool-1-thread-1游泳者0释放了许可(离开了泳道),还剩0个泳道可用~
pool-1-thread-8游泳者7获取了许可(获取了泳道),还剩0个泳道可用~
pool-1-thread-5游泳者4释放了许可(离开了泳道),还剩0个泳道可用~
pool-1-thread-9游泳者8获取了许可(获取了泳道),还剩0个泳道可用~
pool-1-thread-4游泳者3释放了许可(离开了泳道),还剩0个泳道可用~
pool-1-thread-3游泳者2释放了许可(离开了泳道),还剩1个泳道可用~
pool-1-thread-2游泳者1释放了许可(离开了泳道),还剩1个泳道可用~
pool-1-thread-10游泳者9获取了许可(获取了泳道),还剩0个泳道可用~
pool-1-thread-6游泳者5释放了许可(离开了泳道),还剩2个泳道可用~
pool-1-thread-7游泳者6释放了许可(离开了泳道),还剩3个泳道可用~
pool-1-thread-10游泳者9释放了许可(离开了泳道),还剩4个泳道可用~
pool-1-thread-9游泳者8释放了许可(离开了泳道),还剩5个泳道可用~
pool-1-thread-8游泳者7释放了许可(离开了泳道),还剩6个泳道可用~
看了上面的结果,你是不是觉得获取泳道使用权或者释放泳道使用权之后,剩下可用泳道的数量是不是不对呀!其实是没错的,只是因为线程运行太快,acquire()方法或者release()方法在打印语句执行之前,就已经执行了,所以看起来结果才好像不大对。
简单介绍就到这里啦,更多介绍请点击下面链接~
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
已为社区贡献3条内容
所有评论(0)