使用Java实现计数信号量

3

我猜想互斥锁(mutex)和信号量(semaphore)之间的显著区别在于:计数信号量支持多个最大访问,而互斥锁在同一时间只支持最多一个访问。

但是在以下实现时:

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()方法呢?


8
你知道在 java.util.concurrent 中已经有 SemaphoreCountdownLatch 类了吗?还是你正在为作业重新实现这些东西? - skaffman
除非你在一个禁止并发编程的受限环境中使用Java并不得不自己实现,否则这很可能是一项作业。 - Chii
2个回答

1

从概念上讲,您正在寻找一个信号量(它初始化为一个许可证,行为相当于互斥锁)。

如果您无法使用J2SE 5.0,则建议查看其前身util.concurrent,它在公共领域中,并且可以在J2SE 5.0之前的Java版本上进行后移/使用(我也在有限设备上使用了一些派生类)。

请查看Semaphore及其提供顺序的派生类,例如FIFOSemaphore

如果你需要指导和参考书架上的书,我推荐Doug Lea的"Java并发编程实战",他负责了util.concurrent和JSR,为我们带来了java.util.concurrent。

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();
          }
       }
   }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接