Java-可重入锁,can';无法访问新创建的条件

Java-可重入锁,can';无法访问新创建的条件,java,concurrency,locking,conditional-statements,reentrantlock,Java,Concurrency,Locking,Conditional Statements,Reentrantlock,我已经创建了一个新的条件chomptickfree,在我的pickupbooptick()方法中,我正在等待它的锁,但我根本无法访问它 通过调试,我发现当它到达pickupbooptick()方法中的chomptickfree.wait()行时,它只是无限期地暂停 我不明白?构造器中的代码只是不确定地试图让它工作,但不管怎样,我已经创建了一个新的条件,向所有人表明它是免费的,但我根本无法锁定它 public class Chopstick { Lock lock = new Reentr

我已经创建了一个新的条件
chomptickfree
,在我的
pickupbooptick()
方法中,我正在等待它的锁,但我根本无法访问它

通过调试,我发现当它到达
pickupbooptick()
方法中的
chomptickfree.wait()
行时,它只是无限期地暂停

我不明白?构造器中的代码只是不确定地试图让它工作,但不管怎样,我已经创建了一个新的条件,向所有人表明它是免费的,但我根本无法锁定它

public class Chopstick {
    Lock lock = new ReentrantLock();

    private Condition chopstickFree = lock.newCondition();
    private Condition chopstickInUse = lock.newCondition();

    Chopstick() {
        lock.lock();
        chopstickFree.signalAll();
        lock.unlock();
    }

    // Pick up chopstick
    public void pickUpChopstick() throws InterruptedException {
        lock.lock();

        try {
            chopstickFree.await(); // ALWAYS PAUSES HERE INDEFINITELY
            chopstickInUse.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    // Release chopstick
    public void releaseChopstick() {
        lock.lock();
        chopstickFree.signal();
        lock.unlock();
    }
}
有什么想法吗

Cheers

仅向当前在(或其好友)中的线程发送信号,即该信号不排队等待以后的呼叫

您需要另一个受锁保护的标志才能正确实施:

public class Chopstick {
  private final Lock lock = new ReentrantLock();
  private final Condition chopstickFree = lock.newCondition();
  private volatile boolean isFree = true;

  Chopstick() { /* Nothing */ }

  // Pick up chopstick
  public void pickUpChopstick() throws InterruptedException {
    lock.lock();

    try {
      while (!isFree) {
        chopstickFree.await();
      }
      isFree = false;
    } finally {
      lock.unlock();
    }
  }

  // Release chopstick
  public void releaseChopstick() {
    lock.lock();
    try {
      isFree = true;
      chopstickFree.signal();
    } finally {
      lock.unlock();
    }
  }
}

下面是一个使用的版本,其意图可能与原始实现更接近:

public class Chopstick {
  private final Semaphore chopsticksAvailable = new Semaphore(1);

  Chopstick() {
    // Nothing
  }

  // Pick up chopstick
  public void pickUpChopstick() throws InterruptedException {
    chopsticksAvailable.acquire();
  }

  // Release chopstick
  public void releaseChopstick() {
    chopsticksAvailable.release();
  }
}

没有例外,只是无限期的暂停。
chomptick
不可能有两个不同的实例,信号发生在不同的实例上,而不是等待?嗯,有一个ArrayList,其中两个筷子被传递给了另一个类,该类使用了PickupleftChomptick()方法,该方法依次调用Choppestick类中的PickupChoppestick()方法。@mgibson-您是否在与主逻辑运行位置不同的线程中调用
PickupChoppestick
方法?否则你就把自己完全锁在外面了。