Java:从异步任务中检索的排序结果

时间:2011-12-18 18:19:23

标签: multithreading java

我有一个计算(CTR加密),需要精确的结果。

为此,我创建了一个计算所述结果的多线程设计,在这种情况下,结果是ByteBuffer。当然,计算本身是异步运行的,因此结果可以随时以任何顺序变为可用。 “user”是一个单线程应用程序,它通过调用方法来使用结果,之后ByteBuffers通过所述方法返回到资源池 - 资源管理已经被处理(使用线程安全堆栈)。 / p>

现在的问题是:我需要一些可以聚合结果的内容,并以正确的顺序提供它们。如果下一个结果不可用,则用户调用的方法应该阻塞,直到它为止。有没有人知道java.util.concurrent中可以按顺序返回异步计算结果的好策略或类?

解决方案必须是线程安全的。我想避免第三方库,Thread.sleep()/ Thread.wait()和除“synchronized”之外的与标题相关的关键字。此外,任务可以给予例如如果需要,执行程序的顺序正确。这是用于研究,所以随意使用Java 1.6甚至1.7结构。

注意:我已经标记了这些问题[jre],因为我想保留在JRE和[加密]中定义的类中,因为有人可能已经不得不处理它,但问题本身纯粹是关于java& ;多线程。

3 个答案:

答案 0 :(得分:4)

使用executors framework

ExecutorService executorService = Executors.newFixedThreadPool(5);
List<Future> futures = executorService.invokeAll(listOfCallables);
for (Future future : futures) {
   //do something with future.get();
}
executorService.shutdown();

listOfCallables将是您构建的用于操作数据的List<Callable<ByteBuffer>>。例如:

list.add(new SubTaskCalculator(1, 20));
list.add(new SubTaskCalculator(21, 40));
list.add(new SubTaskCalculator(41, 60));

(任意数字范围,根据您手头的任务调整)

.get()阻止,直到结果完成,但同时其他任务也在运行,因此当您联系到它们时,他们的.get()就会就绪。

答案 1 :(得分:1)

以正确的顺序返回结果是微不足道的。当每个结果到来时,将它存储在一个arraylist中,一旦你获得了所有结果,只需对arraylist进行排序。您可以使用PriorityQueue在结果到达时始终对结果进行排序,但这样做是没有意义的,因为在所有结果都到达之前您不会使用结果。

所以,你能做的就是:

声明一个“WorkItem”类,其中包含一个bytearray及其序号,以便可以按序号进行排序。

在你的工作线程中,做一下这样的事情:

...do work and produce a work_item...

synchronized( LockObject )
{
    ResultList.Add( work_item );
    number_of_results++;
    LockObject.notifyAll();
}

在主线程中,执行以下操作:

synchronized( LockObject )
    while( number_of_results != number_of_items )
        LockObject.wait();
ResultList.Sort();
...go ahead and use the results...

答案 2 :(得分:0)

在更好地了解您想要做的事情后,我的新答案:

声明一个“WorkItem”类,其中包含一个bytearray及其序号,以便可以按序号进行排序。

使用按顺序编号排序的java.util.PriorityQueue。基本上,我们关心的是在任何给定时间优先级队列中的第一个项目将是下一个要处理的项目。

每个工作线程将其结果存储在PriorityQueue中,并在某个锁定对象上发出NotifyAll。

主线程等待锁定对象,然后如果队列中有项目,并且队列中(偷看,未出队)第一项的序数等于到目前为止处理的项目数,然后它将项目出列并处理它。如果没有,它会一直等待。如果已经生成并处理了所有项目,则完成。