Java Semaphore
Semaphore(信号量)
信号量(Semaphore)是操作系统中用于控制多个线程对共享资源访问的一种同步机制
基本概念和方法
- 许可:当创建一个Semaphore实例时,需要指定一个许可数,这个数字代表了最多允许多少个线程同时访问受保护的资源。
- 获取许可(acquire()方法):每当一个线程想要访问受保护的资源时,它必须首先调用acquire()方法尝试获得一个许可。如果当前还有可用的许可,则该线程可以继续执行;如果没有可用的许可(即所有许可都已被其他线程占用),则调用acquire()的线程将被阻塞,直到有其他线程释放了一个许可。
- 释放许可(release()方法):一旦线程完成了对共享资源的访问,它应该调用release()方法来释放其持有的许可,使得其他等待的线程有机会获取许可并访问资源。
深入理解原理
- 内部队列:当没有可用的许可时,试图获取许可的线程会被放入一个等待队列中。这个队列由AQS(AbstractQueuedSynchronizer)管理,确保线程能够有序地获取到许可。
- 公平性:如果Semaphore被配置为公平模式,那么等待时间最长的线程将优先获得许可。这有助于避免饥饿问题,但可能会降低整体性能。
- 非公平性:默认情况下,Semaphore是非公平的,这意味着新到达的线程有机会“插队”直接尝试获取刚刚被释放的许可,而不需要排队等候。
重点思路
- 唤醒过程:AQS会遍历等待队列中的节点,使用LockSupport.unpark()方法来恢复那些之前被挂起的线程。被唤醒的线程将再次尝试获取许可。如果此时有可用的许可(即信号量的许可计数大于0),那么该线程将成功获取许可并退出等待状态,继续执行其后续代码。如果没有可用的许可,则该线程可能会再次进入等待状态,或者根据实现细节进行短暂的自旋后再尝试获取。