有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

我应该使用什么同步原语在Java中实现事件驱动程序框架?

我有一个活套线程来执行任务。其他线程可以将任务提交到此循环器线程。有些任务是即时任务,有些是未来任务,将在提交后T秒后执行。我使用PriorityBlockingQueue存储任务,其中时间被用作优先级,因此队列的第一个任务是要执行的最紧迫的任务

活套的主回路如下所示:

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
}

looper允许其他线程(或自身)提交任务:

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.
}

在这里,我只有一个线程调用wait(),多个线程调用signal()。我的问题是我应该用什么同步原语来代替<something>。在java.util.concurrentjava.util.concurrent.lock包中有很多原语。还有synchronized关键字和Object.wait()/notify()。哪一个最适合这里


共 (2) 个答案

  1. # 1 楼答案

    你不需要做这些

    BlockingQueue的全部要点是它已经为您管理线程同步。您不需要通知其他线程现在有新的可用内容

    使用

     taskQueue.take(); // blocks until something is there
    

     taskQueue.poll(1, SECONDS); // wait for a while then give up
    

    对于不应立即处理的“未来任务”,我根本不会将它们添加到此队列中。一旦到了时间,您可以使用ScheduledExecutorService将它们添加到任务队列中(实际上是第二个队列)

    仔细想想,您可以完全取消阻塞队列,只需使用ScheduledExecutorService(由单个线程支持,即您的“循环器”)即可完成所有任务

  2. # 2 楼答案

    j.u.c.包中包含DelayedQueue,可以满足您的问题。 每个排队对象都应该使用getDelay(..)实现延迟接口方法