java Semaphore原理

虽然JDK已经提供了Semaphore相关实现,但是还是很有必要去熟悉如何使用Semaphore及其背后的原理。

做一个简单的Semaphore实现

Java代码  收藏代码
  1. class SemaphoreTest {  
  2.     private boolean signal = false;  
  3.     public synchronized void take() {  
  4.         this.signal = true;  
  5.         this.notify();  
  6.     }  
  7.     public synchronized void release() throws InterruptedException {  
  8.         while (!this.signal)  
  9.             wait();  
  10.         this.signal = false;  
  11.     }  
  12. }  

 

使用这个semaphore可以避免错失某些信号通知。用take方法来代替notify,release方法来代替wait。如果某线程在调用release等待之前调用take方法,那么调用release方法的线程仍然知道take方法已经被某个线程调用过了,因为该Semaphore内部保存了take方法发出的信号。而wait和notify方法就没有这样的功能。

 

可计数的Semaphore

Java代码  收藏代码
  1. class SemaphoreTest {  
  2.     private int signals = 0;  
  3.     public synchronized void take() {  
  4.         this.signals++;  
  5.         this.notify();  
  6.     }  
  7.     public synchronized void release() throws InterruptedException {  
  8.         while (this.signals == 0)  
  9.             wait();  
  10.         this.signals--;  
  11.     }  
  12. }  

 

Semaphore上限

Java代码  收藏代码
  1. class SemaphoreTest {  
  2.     private int signals = 0;  
  3.     private int bound = 0;  
  4.     public SemaphoreTest(int upperBound) {  
  5.         this.bound = upperBound;  
  6.     }  
  7.     public synchronized void take() throws InterruptedException {  
  8.         while (this.signals == bound)  
  9.             wait();  
  10.         this.signals++;  
  11.         this.notify();  
  12.     }  
  13.     public synchronized void release() throws InterruptedException {  
  14.         while (this.signals == 0)  
  15.             wait();  
  16.         this.signals--;  
  17.         this.notify();  
  18.     }  
  19. }  

 

当已经产生的信号数量达到了上限,take方法将阻塞新的信号产生请求,直到某个线程调用release方法后,被阻塞于take方法的线程才能传递自己的信号。

 

把Semaphore当锁来使用
当信号量的数量上限是1时,Semaphore可以被当做锁来使用。通过take和release方法来保护关键区域。

posted @ 2015-05-02 16:42  牧 天  阅读(630)  评论(0)    收藏  举报