Java优先级队列等待

Java优先级队列等待,java,multithreading,Java,Multithreading,我试图用多线程技术解决Java中的读写器偏好问题。下面是我的代码的精简版本。行吗 public PriorityQueue<myClass> pq; public void foo(){ myClass obj = new myClass(); pq.add(obj); obj.wait(); //Actual code } public void bar(){ pq.remove().notify(); } 假设优先级队列pq最初为空,并且

我试图用多线程技术解决Java中的读写器偏好问题。下面是我的代码的精简版本。行吗

public PriorityQueue<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先被称为foo,然后被称为bar。因此,当调用foo时,它会将obj添加到队列中,并成为前面的元素,因此当在bar中调用remove时,它就是被移除的元素。我的问题是,实际的代码会被执行吗?还是我在两个完全不同的对象上执行等待和通知?如果是这样,我如何修复它?

您应该注意这不是线程安全的。。。i、 e.如果同时调用foo和/或bar,它们可能会不可修复地破坏pq的内部状态。

您应该注意,这不是线程安全的。。。i、 e.如果同时调用foo和/或bar,它们可能会不可修复地破坏pq的内部状态。

我仍在尝试解析您的问题,到目前为止,我可以提取的是,您希望为显示writer首选项的myClass实现优先级队列。Java的现成锁不提供严格的writer首选项,但是如果您还可以,并且使用近似writer首选项可能是最好的,那么您可以在fair模式下使用normal

写了所有这些并考虑了可能出现错误的多种方式后,我真的想知道的java.util.concurrent实现为什么不能满足您的需要

下面的代码远未经过测试,但通过了我凌晨1:00的嗅探测试

private final PriorityQueue<myClass> pq = ...;
// associated RW lock, in fair mode (==true)
private final ReadWriteLock pqLock = new ReentrantReadWriteLock(true);    
private final Condition pqWriteCondition = pqLock.writeLock().newCondition();    

public void produceNew()
{
    myClass obj = new myClass();
    pqLock.writeLock.lock();
    try { 
      pq.offer(obj);
      pqWriteCondition.notifyAll();
    } finally {
      pqLock.writeLock.unlock();
    } 
    //Actual code
}

public void consumeFirst() {
    myClass consume = null;
    pqLock.readLock.lock();
    try { 
      consume = pq.poll();
      while (consume == null) {
        pqWriteCondition.wait();
        consume = pq.poll();
      }
    } finally {
      pqLock.readLock.unlock();
    } 
    //Actual code

}

我仍在尝试解析您的问题,到目前为止,我可以提取的是,您希望为myClass实现一个显示编写器首选项的优先级队列。Java的现成锁不提供严格的writer首选项,但是如果您还可以,并且使用近似writer首选项可能是最好的,那么您可以在fair模式下使用normal

写了所有这些并考虑了可能出现错误的多种方式后,我真的想知道的java.util.concurrent实现为什么不能满足您的需要

下面的代码远未经过测试,但通过了我凌晨1:00的嗅探测试

private final PriorityQueue<myClass> pq = ...;
// associated RW lock, in fair mode (==true)
private final ReadWriteLock pqLock = new ReentrantReadWriteLock(true);    
private final Condition pqWriteCondition = pqLock.writeLock().newCondition();    

public void produceNew()
{
    myClass obj = new myClass();
    pqLock.writeLock.lock();
    try { 
      pq.offer(obj);
      pqWriteCondition.notifyAll();
    } finally {
      pqLock.writeLock.unlock();
    } 
    //Actual code
}

public void consumeFirst() {
    myClass consume = null;
    pqLock.readLock.lock();
    try { 
      consume = pq.poll();
      while (consume == null) {
        pqWriteCondition.wait();
        consume = pq.poll();
      }
    } finally {
      pqLock.readLock.unlock();
    } 
    //Actual code

}

假设我使用PriorityBlockingQueue。我的问题仍未解决。假设我使用PriorityBlockingQueue。我的问题还没有解决。你能说说你想发生什么吗?您所说的编写器首选项是什么意思,特别是在示例代码的上下文中?可能foo和bar是从不同的线程调用的。。。你想让foo让一个对象排队,然后阻塞直到bar让它排队?为什么?还有,这与这里非常相似的问题有什么关系?这是同一个问题。我等了大约10-12个小时,似乎没有人回应,所以我认为这个问题是所有人都会再次注意到的问题,这就是我再次发布这个问题的原因。@andersoj:我必须根据作者偏好来写政策。正因为如此,我无法使用notify。它是这样的:两个队列,分别为等待的读者和作者。队列是一种自定义RequestObject类型,其中包含一个表示请求优先级的整数。每个请求对象上只有一个线程等待,所以我可以选择在线程执行完成时释放哪个线程,而不是让Java来决定。我的错误是,我没有在等待和通知之间放置一个synchronizedobj和一个类似的synchronizedobj。你能说一下你想发生什么吗?您所说的编写器首选项是什么意思,特别是在示例代码的上下文中?可能foo和bar是从不同的线程调用的。。。你想让foo让一个对象排队,然后阻塞直到bar让它排队?为什么?还有,这与这里非常相似的问题有什么关系?这是同一个问题。我等了大约10-12个小时,似乎没有人回应,所以我认为这个问题是所有人都会再次注意到的问题,这就是我再次发布这个问题的原因。@andersoj:我必须根据作者偏好来写政策。正因为如此,我无法使用notify。它是这样的:两个队列,分别为等待的读者和作者。队列是一种自定义RequestObject类型,其中包含一个表示请求优先级的整数。每个请求对象上只有一个线程等待,所以我可以选择在线程执行完成时释放哪个线程,而不是让Java来决定。我的错误是,我没有在等待和通知周围放置synchronizedobj和类似的synchronized。我的代码不起作用,因为我在执行等待和通知时没有在适当的对象上使用同步块。我相信你的代码也会受到类似的影响。很有趣。。。并不是说我已经仔细测试过了,但它与我在生产中使用的代码类似。通常,对于受读/写锁保护的对象,写锁条件是执行此操作的正确位置。你有没有看报纸
rBlock API?另外,如果您没有使用j.u.并发锁和条件,而是使用裸java监视器w/wait和notify,那么这里有一个相关的问题:@Meher,哦,我看到您看到的了。否,wait和notify在条件实例上的工作方式不同,条件实例会覆盖Object.wait默认实现。不需要同步,但您确实需要。如我所做的那样锁定相应的锁。我的代码不起作用,因为我在执行等待和通知时没有对适当的对象使用同步块。我相信你的代码也会受到类似的影响。很有趣。。。并不是说我已经仔细测试过了,但它与我在生产中使用的代码类似。通常,对于受读/写锁保护的对象,写锁条件是执行此操作的正确位置。你看过rwlockapi了吗?另外,如果你没有使用j.u.concurrent锁和条件,而是使用裸java监视器w/wait和notify,这里有一个相关的问题:@Meher,哦,我看到你看到的了。否,wait和notify在条件实例上的工作方式不同,条件实例会覆盖Object.wait默认实现。不需要同步,但您确实需要。像我所做的那样锁定相应的锁。