Semaphore信号量
目录
Semaphore是计数信号量。Semaphore可管理1个或多个许可证。
- acquire()方法尝试获取一个许可证,如果没有获得到,当前线程阻塞,直至其它线程的release()方法释放出来一个许可证;
- release()方法释放出来一个许可证;
Semaphore含义:有多少许可证,就能同时允许多少线程并行。这要看当前机器CPU的最大线程支持数N(理论上来说,程序上给与设定的最佳并发线程数为N+1)。信号量主要用于两个目的:一个是用于多个共享资源的互斥使用,另一个用于并发线程数的控制。下面举例说明业务场景。
示例1:生产者消费者----产1消1模式
产1消1:业务说明
- 业务初始情况:
原料若干,生产者1人,消费者1人,加工房1间(共享资源)。
- 业务达到效果:
生产者每加工出来一个原料,则消费者立马取走消费。
- 业务注意事项:
生产者和消费者不用共用一个信号指示灯,原因是由于并发性,有可能生产者总是能获得到许可证,疯狂的生产导致生产过剩,消费饥饿现象;也有可能消费者总是能获得到许可证,疯狂的消费导致消费过剩(其实啥都没消费到,因为还没生产呢),生产饥饿现象;所以,生产者/消费者的并发问题,我们在此启用一个生产信号指示灯,一个消费信号指示灯。生产者获得可生产的指示灯后,进行生产直至生产完毕,然后点亮消费信号指示灯使消费者具备资格进行消费。消费者获得可消费的指示灯后,进行消费直至消费完毕,然后点亮生产信号指示灯使生产者具备资格进行生产。
系统初始时,加工房共享资源是空闲着的,有硬性要求必须要先进行生产,然后才能消费。
- 业务实现图示:
- 业务示例代码:
/**
* Thread线程:代码结构的一般写法
* 业务类:包含共享资源以及共享资源的访问方法
* 任务:实现Runnable,一个任务代表一个业务类需要并发执行的业务方法
//业务类
class MyClass{
private int n; //共享资源
public void set(int n){
this.n = n;
}
public int get(){
return n;
}
}
//任务
class MyTask implements Runnable{
private Semaphore sem ;//同步器|锁
private MyClass myObj; //业务类对象
public MyTask(MyClass myObj, Semaphore sem){
this.sem = sem;
this.myObj = myObj;
}
public void run(){
sem.acquire(); //获得锁
myObj.yyyMethod(); //临界区:业