I have a Thread that handles operations in a queue. Basically, loop forever. If there are operations in the queue, dequeue an operation and execute it. If there are no operations, wait until you’re told there are.
In pseudo code (ignore critical sections for now):
public class OperationHandler extends Thread {
private Deque<Operation> queue = new LinkedList<>();
public void run() {
while (true) {
if (queue isn't empty) {
dequeue the operation and execute it
}
else {
wait;
}
}
}
public void operationRequired() {
add operation to queue
notify yourself / return to infinite while loop
}
}
Basically a Controller class initializes this OperationHandler and start()s it. Whenever some requests arrives, the controller calls operationRequired on the thread so that the operations is handled asynchronously in the infinite while loop. Is there any way to achieve this?
I’ve tried with this.wait() and this.notify() but I get either deadlock or IllegalMonitorStateException depending on different synchronized blocks.
You can’t get a Thread to notify itself since it is blocked in
wait(). You can have another thread notify the thread by synchronizing on the same object that the thread is locking on and callingnotify(). See the below code for a sample.That said, I’d recommend using a
BlockingQueueto share data in this respect. It takes care of all of the locking and signaling. All the thread does is calltake()and it will wait for the next operation to be added to the queue with aput().Lastly, it’s always recommended to implement
Runnableinstead of extendingThread. Once you turn your thread into a runnable you can use theExecutorServiceclasses as @Peter mentions in his answer. With anExecutorServiceyour code would look like:But if you still want to tweak your code to get it to work: