Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 线程状态永远不会唤醒_Java_Multithreading - Fatal编程技术网

Java 线程状态永远不会唤醒

Java 线程状态永远不会唤醒,java,multithreading,Java,Multithreading,我有一个线程,当它运行时,它会创建一个消息对象,并将其放入监视器中的链接列表中。同时,另外两个线程等待此列表获取其中的消息对象,一段时间后(linkedlist.isEmpty())canGetMessage.await();循环,但即使我正在发送canGetMessage.signalAll();命令将对象放入列表时,其他两个线程永远不会唤醒 public void deliverMessage(Message m){ lock.lock(); try{ linkedlist.add(m

我有一个线程,当它运行时,它会创建一个消息对象,并将其放入监视器中的链接列表中。同时,另外两个线程等待此列表获取其中的消息对象,一段时间后(linkedlist.isEmpty())canGetMessage.await();循环,但即使我正在发送canGetMessage.signalAll();命令将对象放入列表时,其他两个线程永远不会唤醒

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(我同意,这是一个更好的解决方案)。。。或者删除你的问题。