【问题标题】:Mutex not being respected in synchronized methods in Java class在 Java 类的同步方法中不尊重互斥锁
【发布时间】:2010-01-26 10:02:36
【问题描述】:

我的 Queue 类在负载下遇到互斥问题,我不知道为什么会发生这些问题。

objects = new ArrayList<Object>();
public synchronized int getSize(){
 return objects.size();
}

public synchronized Object dequeue(){
 if(getSize()==0){
  try {
   wait();
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
 return objects.remove(0);
}

public synchronized void enqueue(Object o){
 objects.add(o);
 notify();
}

似乎一段时间后的 dequeue 方法会导致 Java.lang.IndexOutOfBoundsException ,在我看来,线程已经能够多次调用 dequeue 方法,而它不应该如此。有什么想法???

W

【问题讨论】:

    标签: java multithreading mutex


    【解决方案1】:

    wait() 有可能返回另一个线程调用notify(),这将解释您所看到的异常。

    试试

    while(getSize()==0)
    

    notifyAll();
    

    而不是

    if(getSize()==0)
    

    notify();
    

    【讨论】:

    • 干杯 m8.. 作为一个简短的跟进,我的单元测试还不够先进,无法接受这个。您可以推荐的任何方法 - 我一直想研究 groboutils,因为 junit 并不真正适合多线程测试。
    • @imerez - 作为一个新问题提出这个问题。
    【解决方案2】:

    当多个线程在 dequeue 方法中等待并唤醒或收到 InterruptedException(由于通知以外的原因)时,即使队列为空,它们也会尝试将对象从队列中取出。

    如果您将方法更改为:

    public synchronized Object dequeue(){
     while (getSize()==0){
      try {
       wait();
      } catch (InterruptedException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
      }
     }
     return objects.remove(0);
    }
    

    问题应该已经解决了,作为奖励,您可以使用 notifyAll() 而不是依赖于 notify 的行为。

    【讨论】:

    • 它可能不是InterruptedException。这将显示在堆栈跟踪中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-10
    • 1970-01-01
    • 2014-05-02
    • 1970-01-01
    • 1970-01-01
    • 2012-08-28
    相关资源
    最近更新 更多