You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
|
|
|
|
|
|
|
信号量是一种变量或抽象数据类型,用于控制并发系统中多个进程对公共资源的访问。
|
|
|
|
|
以一个停车场的运作为例。简单起见,假设停车场只有三个车位,一开始三个车位都是空的。这时如果同时来了五辆车,看门人允许其中三辆直接进入,然后放下车拦,剩下的车则必须在入口等待,此后来的车也都不得不在入口处等待。这时,有一辆车离开停车场,看门人得知后,打开车拦,放入外面的一辆进去,如果又离开两辆,则又可以放入两辆,如此往复。 在这个停车场系统中,车位是公共资源,每辆车好比一个线程,**看门人**起的就是信号量的作用。
|
|
|
|
|
|
|
|
|
|
Semaphore是Java多线程兵法中的一种JDK内置同步器,通过它可以实现多线程对公共资源的并发访问控制。一个线程在进入公共资源时需要先获取一个许可,如果获取不到许可则要等待其它线程释放许可,每个线程在离开公共资源时都会释放许可。其实可以将Semaphore看成一个计数器,当计数器的值小于许可最大值时,所有调用acquire方法的线程都可以得到一个许可从而往下执行。而调用release方法则可以让计数器的值减一。
|
|
|
|
|
|
|
|
|
|
## 一、信号量的分类
|
|
|
|
|
|
|
|
|
|
+ 计数信号量:信号量是一个任意的整数
|
|
|
|
|
+ 二值信号量:只有二进制的0或1(互斥锁)
|
|
|
|
|
## 二、信号量的工作机制
|
|
|
|
|
|
|
|
|
|
信号量的值表示用于控制并发系统中多个进程对公共资源的访问,只有P/V操作能够修改信号量的值
|
|
|
|
|
|
|
|
|
|
P(pass):
|
|
|
|
|
+ 完成一次wait(),信号量值减一,如果新的信号量值大于0,则进入临界区
|
|
|
|
|
+
|
|
|
|
|
+ 如果新的信号量的值小于0,那么该进程将被阻塞(被添加到semaphor的等待进程队列里面waiting queue)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
V(release):
|
|
|
|
|
+ 完成一次signal(),信号量值加一,如果递增之前,semaphore的值小于0(表示有进程正在等待获取资源),从waiting queue中挑选一个进程到ready queue里面
|
|
|
|
|
|
|
|
|
|
## 三、案例
|
|
|
|
|
|
|
|
|
|
多线程交替打印,当semaphore初始化为1时,调用first.acquire()方法可以进入临界区执行后续代码。当sec.release()执行时,sec会加1,因此bar()中的sec.acquire() 方法不会阻塞。
|
|
|
|
|
![[Pasted image 20231114173941.png]]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 四、原理
|
|
|
|
|
|
|
|
|
|
基于AQS的共享模式实现,参考[[锁#五、AQS]]
|