读取器/写入器使用等待和通知,如果达到项目的时间戳,读者只能从队列中获取



我有一个任务的优先级队列(具有同步访问权限)。每个任务都有一个执行时间。当要执行队列前面的任务时,它应该从队列中弹出,但之前不能弹出,因为可以在队列中的前面添加一些内容。(即具有较早的时间戳)。此外,该任务可以在执行之前从Q中删除。

这么多我想我有(sudo代码)

public synchronized task Q.get(){
while Q.empty(){
wait();
}
// queue is not empty
if (Q.head.time.isBefore(now)){ // task at head of Q is due to be done
return Q.pop();
}else{
// THIS IS WHERE IM STUCK ***
}

*点:

我可以写代码让它一直睡到队列头的任务时间,然后接受它。这里的问题是我们锁定了Q,所以在睡觉时不能添加任务??此外,如果在队列的开头添加了一些内容(尽管我不确定是否可以),那么读者就会睡得太久。

我还认为我可以再次在Q上写wait()的代码,但在设置了一个计时器(队列拥有的一个单独线程在队列开头的任务时纯粹为Q.notify)之后。我看到的问题是,如果有东西放在Q的头上,我们会中断计时器并在Q上通知,然后读者会接受新的头任务,而不检查时间。

如有任何帮助,我们将不胜感激,提前表示感谢。我在这方面相当缺乏经验,所以请纠正任何错误的假设等。

编辑。阅读器类简单地循环,通过调用Q.get()并对其进行操作来获得下一个任务。

我不知道你的代码是如何使用这种方法的,但你可以

  1. 在您的else中返回null或
  2. 添加一个循环,检查第一个Task是否应该现在已经执行

第二种方法的代码如下:

public synchronized task Q.get(){
while Q.empty(){
wait();
}
// queue is not empty
while (!Q.head.time.isBefore(now)){
//instead of writing 100 you can calculate the time between now 
//and the first scheduled task
wait(100); 
}
return Q.pop();
}

java.util.concurrent包中有很多有用的类。查看优先级阻塞队列:

http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/PriorityBlockingQueue.html

您可以运行两个线程——一个线程写入队列,另一个线程从队列中读取。它包含方法take(),它会阻塞,直到队列中有东西为止,所以您不必使用wait()

如果时间不早于现在,您只需offer()即可将所获取的对象返回到队列中。如果对象的顺序是基于它将存储在队列中正确位置的时间。

您的对象的顺序可以使用以下构造函数用Comparator定义:

http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/PriorityBlockingQueue.html#PriorityBlockingQueue(int,java.util.Comprator)

如果您对Comparable和Comparator接口了解不多,请查看:

Java:Comparable与Comparator

这对你来说可能也很有趣:

http://tutorials.jenkov.com/java-util-concurrent/delayqueue.html

最新更新