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



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

为此,我创建了一个多线程设计来计算上述结果,在这种情况下,结果是一个ByteBuffer。计算本身当然是异步运行的,因此可以在任何时间以任何顺序获得结果。"用户"是一个单线程应用程序,它通过调用一个方法来使用结果,之后ByteBuffers通过该方法返回到资源池中——资源的管理已经处理好了(使用线程安全堆栈)。

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

解决方案必须是线程安全的。我想避免第三方库,Thread.sleep()/Thread.wait()和标题相关的关键字,而不是"synchronized"。此外,如有需要,这些任务可按正确的顺序交给执行人。这是为了研究,所以可以随意使用Java 1.6甚至1.7的结构。

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

使用执行器框架:

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()将准备好。

以正确的顺序返回结果是微不足道的。当每个结果到达时,将其存储在数组列表中,一旦获得所有结果,就对数组列表进行排序。您可以使用PriorityQueue在结果到达时始终保持排序,但是这样做没有意义,因为在所有结果到达之前您将不会使用任何结果。

那么,你可以这样做:

声明一个"WorkItem"类,它包含一个字节数组和它的序数,这样它们就可以按序数排序。

在你的工作线程中,这样做:

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

在更好地了解你想做什么之后,我的新答案:

声明一个"WorkItem"类,其中包含一个字节数组和它的序数,以便它们可以按序数排序。

使用java.util.PriorityQueue,它按序号进行排序。从本质上讲,我们所关心的只是在任何给定时间优先级队列中的第一个项目将是下一个要处理的项目。

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

主线程等待锁定对象,然后如果队列中有项目,并且队列中第一个项目的序号(窥视的,未退出队列的)等于到目前为止已处理的项目数,则将该项目从队列中退出并处理它。如果没有,它会继续等待。如果所有的项目都已生产和处理,则完成。

最新更新