I have a looper thread to execute tasks. Other threads can submit tasks to this looper thread. Some tasks are immediate tasks, others are future tasks, which are to be executed after T seconds after submission. I use PriorityBlockingQueue
to store tasks, where time is used as the priority, so that the first task of the queue is the most imminent task to be executed.
The looper's main loop is as fellows:
PriorityBlockingQueue<Event> taskQueue = ...
while (true) {
if (taskQueue.isEmpty())
<something>.wait(); // wait indefinitely
else
<something>.wait(taskQueue.peek().time - NOW()); // wait for the first task
Task task = taskQueue.poll(0); // take the first task without waiting
if (task != null && task.time <= NOW())
task.execute();
else if (task != null)
taskQueue.offer(task); // not yet runnable, put it back
}
The looper provides allows other threads (or itself) to submit tasks:
public void submitTask (Task task) { // time information is contained in the task.
taskQueue.offer(task);
<something>.signal(); // informs the loop thread that new task is avaliable.
}
Here, I have only one thread calling wait()
and multiple threads calling signal()
. My question is that what synchronization primitive should I use in the place of <something>
. There are so many primitives in the java.util.concurrent
and java.util.concurrent.lock
package. And there are also the synchronized
keyword and Object.wait()/notify()
. Which one fits best here?
j.u.c. package contains DelayedQueue which can satisfy you problem. Every queued object should implement Delayed interface with getDelay(..) method.