Java PriorityQueue Wait
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 PriorityQueue<myClass> pq;
public void foo(){
myClass obj = new myClass(开发者_Go百科);
pq.add(obj);
obj.wait();
//Actual code
}
public void bar(){
pq.remove().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 and then bar. 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?
You should note that PriorityQueue is not thread safe... i.e. if foo and/or bar is called concurrently they may irreparably break pq's internal state.
I'm still trying to parse your question, and so far what I can extract is that you want to implement a priority queue for myClass
that exhibits writer preference. Java's off-the-shelf locks don't offer strict writer preference, but if you are OK (and it's probably best) with approximate writer preference, you can use a normal ReentrantReadWriteLock in fair mode.
Having written all this (and thought about the many ways it could go wrong) I really wonder why the java.util.concurrent
implementation of PriorityBlockingQueue
doesn't meet your need.
The following code is far from tested, but passes my 1:00AM sniff test.
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
}
精彩评论