I have producer and consumer connected with BlockingQueue
.
Consumer wait records from queue and process it:
Record r = mQueue.take();
process(r);
I need pause this process for a while from other thread. How to implement it?
Now I think implement it such, but it's looks like bad solution:
private Object mLock = new Object();
private boolean mLocked = false;
public void lock() {
mLocked = true;
}
public void unlock() {
mLocked = false;
mLock.notify();
}
public void run() {
....
Record r = mQueue.take();
if (mLocked) {
mLock.wait();
}
process(r);
}
I think your solution is simple and elegant, and think you should keep it with some modifications. The modifications I propose are synchronization.
Without it, thread interference and memory consistancy errors can (and very often does) occur. On top of that, you can't wait
or notify
on a lock you don't own (and you own it if you have it inside a synchronized
block..). The fix is easy, just add a mLock
synchronize block where you wait/notify on it. Also, as you're changing mLocked
from a different thread you will want to mark it volatile.
private Object mLock = new Object();
private volatile boolean mLocked = false;
public void lock() {
mLocked = true;
}
public void unlock() {
synchronized(mlock) {
mLocked = false;
mLock.notify();
}
}
public void run() {
....
Record r = mQueue.take();
synchronized(mLock) {
while (mLocked) {
mLock.wait();
}
}
process(r);
}