Java 线程状态永远不会唤醒
我有一个线程,当它运行时,它会创建一个消息对象,并将其放入监视器中的链接列表中。同时,另外两个线程等待此列表获取其中的消息对象,一段时间后(linkedlist.isEmpty())canGetMessage.await();循环,但即使我正在发送canGetMessage.signalAll();命令将对象放入列表时,其他两个线程永远不会唤醒Java 线程状态永远不会唤醒,java,multithreading,Java,Multithreading,我有一个线程,当它运行时,它会创建一个消息对象,并将其放入监视器中的链接列表中。同时,另外两个线程等待此列表获取其中的消息对象,一段时间后(linkedlist.isEmpty())canGetMessage.await();循环,但即使我正在发送canGetMessage.signalAll();命令将对象放入列表时,其他两个线程永远不会唤醒 public void deliverMessage(Message m){ lock.lock(); try{ linkedlist.add(m
public void deliverMessage(Message m){
lock.lock();
try{
linkedlist.add(m);
canGetMessage.signalAll();
}finally{
lock.unlock();
}
}
public Message getMessage(){
lock.lock();
try{
while(linkedlist.isEmpty()){
canGetMessage.await();
}
return linkedlist.remove(); //returns the item that has been in the list the longest
}
catch (InterruptedException e) { } //not required to handle these
finally{
lock.unlock();
}
我有println来查看它何时脱离while循环,但这从未发生过,我不知道为什么
编辑:只是指定一下,我使用的锁是一个可重入锁猜测;您在这里遇到了问题:
lock.lock();
如果发送方/接收方使用相同的锁定对象,则此操作无法工作。接收器获取锁;并且在发件人将新条目添加到列表中之前不会释放它
但发送者无法到达该部分;因为发送方试图锁定已锁定的锁。因此,锁定的锁将阻塞
“正确”的答案是使用连接发送者/接收者的方法,而不是重新发明“队列”之类的东西。有关如何使用BlockingQueue的更多信息,请参阅。我向大家道歉,问题在于线程本身的创建,我无意中为每个线程制作了单独的监视器,而不是全部使用同一个监视器…为什么不使用生产者-消费者模式的BlockingQueue?发布一个完整的示例来重现这个问题。什么类型的监视器是
lock
,linkedlist
和canGetMessage
,它们是如何创建的?是的,这将非常有用。不,canGetMessage.await()释放锁(假设条件是从该锁创建的)。可能。。。让我们看看OP是怎么说的。如果这对他没有帮助,我不介意删除答案。@Telanore你不应该使用单独的锁。如果你想要一个解释,发布一个完整的最小的例子来重现这个问题。或者继续使用BlockingQueue(我同意,这是一个更好的解决方案)。。。或者删除你的问题。