在Java中将对象放入优先队列后等待对象 [英] Waiting on objects after putting them into priority queue in Java

查看:60
本文介绍了在Java中将对象放入优先队列后等待对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用多线程解决 Java 中编写者偏好的读者-编写者问题.以下是我的代码所做的精简版本.它会起作用吗?

I am trying to solve the readers-writers problem with writer preference in Java using multi-threading. The following is a stripped down version of what my code does. Will it work?

public PriorityBlockingQueue<myClass> pq;
public void foo(){
    myClass obj = new myClass();
    pq.add(obj);
    obj.wait();
    //Actual code
}
public void bar(){
    pq.remove().notify();
}

假设优先级队列 pq 最初是空的,并且封闭类的构造函数调用了 pq 的构造函数.此外, foo 首先由一个线程调用,然后由另一个线程调用 bar.因此,当 foo 被调用时,它会将 obj 添加到队列中并成为最前面的元素,这样当在 bar 中调用 remove 时,它​​就是被删除的元素.我的问题是,实际代码"会被执行吗?还是我在两个完全不同的对象上执行 wait() 和 notify() ?如果是这样,我该如何解决?

Assume that the priority queue pq is empty initially and the constructor of the enclosing class calls the constructor of pq. Also, foo is called first by one thread and then bar by another thread. So when foo is called, it adds obj to the queue and that becomes the front element so that when the remove is called in bar that is the element that is removed. My question is, will "Actual code" be executed? Or am I performing wait() and notify() on two completely different objects? If so, how can I fix it?

推荐答案

我可以看到的主要问题是线程可能会虚假唤醒......所以你应该总是有一些与条件相关的数据.另外notifyAll() 不太可能导致死锁...所以:

The main issue I can see with this is that threads can wake up spuriously... so you should always have some data associated with conditions. Also notifyAll() is less likely to result in deadlock... so:

public void foo() {
     MyClass obj = new MyClass();
     pq.add(obj);
     synchronized(obj) {
         while (!obj.isDoneBeingProcessed()) {
             obj.wait();
         }
      }
 }

 public void bar() {
      MyClass next = pq.remove();
      if (!next) {
          return;
      }
      next.doProcessing();
      synchronized(next) {
          next.setDone(true);
          next.notifyAll();
      }
 }

但是请注意,这段代码确实没有意义,因为它本质上是序列化了整个计算.如果您将所有内容都放入一个线程中,而在另一个线程中进行处理,然后……仅在最后或在另一个线程中尝试等待所有内容,那将更有意义.在所有东西都被有效地生产之前,在生产者阶段等待可以有效地序列化你的整个计算.

Note, though, that this code really doesn't make sense because it essentially serializes the entire computation. It would make more sense if you were to enqueue everything in one thread, while in another thread you did the processing, and then ... only at the end or in another thread attempted to wait on everything. Putting the wait in the producer phase before everything has been produced effectively serializes your entire computation.

这篇关于在Java中将对象放入优先队列后等待对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆