使用java实现计数信号量

时间:2010-01-25 23:20:51

标签: java concurrency semaphore

我怀疑互斥锁和信号量之间的显着差异在于计数信号量支持多个访问权限,因为mutext一次最多只支持一次访问。

但在执行时如下;

public class countingSemaphore{
 private static final int _MOSTTABLES = 3;  // whatever maximum number
 private static int availtable = _MOSTTABLES;

 public synchronized static void Wait(){  
  while(availtable==0){  
   try{
    wait();    
   }
   catch(InterruptedException e){
    e.printStackTrace();
   }
  }
  availtable--;  
 }

 public synchronized static void Signal(){
  while(availtable==_MOSTTABLES){
   try{
    wait();
   }
   catch(InterruptedException e){
    e.printStackTrace();
   }
  }
  availtable++;  
 }
}

问题是调用对象的非静态wait()方法。但是,我必须将同步应用于类而不是对象的实例,因为访问是在多个实例之间共享的。

如何解决wait()错误?我们在java中有另一种方法,或者我们必须自己实现wait()吗?

2 个答案:

答案 0 :(得分:1)

从概念上讲,您正在寻找信号量(使用一个许可证进行初始化,其行为与Mutex相同)。

如果您不能使用J2SE 5.0,那么我建议查看它的前身util.concurrent,它位于Public Domain中,可以在J2SE 5.0之前在Java版本上反向移植/使用(我已经使用了一些派生类)有限的设备)。

查看Semaphore及其提供衍生类的订单,例如FIFOSemaphore

如果您需要书架的指导和参考,我建议由负责"Concurrent Programming in Java"的Doug Lea和带给我们java.util.concurrent的JSR的util.concurrent

答案 1 :(得分:0)

这里有很多其他问题要处理(如果你正在尝试实现并发控制对象),但是对于如何使用静态级别构造的等待/通知机制的特定问题的一个解决方案就是从构造中解开监视器的概念:使用类的静态方法,但是对静态方法引用的对象(任何对象)的特定实例执行同步。例如:

public class MySemaphore {
   // ...
   private final Object lock = new Object();

   public static void acquire(int count) {
       while( ...) {
          synchronized(lock) {
              lock.wait();
          }
       }
   }
   public static void release(int count) {
       while( ...) {
          synchronized(lock) {
              lock.notifyAll();
          }
       }
   }
}