有 Java 编程相关的问题?

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

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

我有一个计算(CTR加密),它要求结果按精确顺序排列

为此,我创建了一个多线程设计来计算所述结果,在本例中,结果是ByteBuffer。当然,计算本身是异步运行的,因此结果可能在任何时间以任何顺序可用。“用户”是一个单线程应用程序,它通过调用一个方法来使用结果,然后通过所述方法将ByteBuffers返回到资源池——资源管理已经完成(使用线程安全堆栈)

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

解决方案必须是线程安全的。我想避免第三方库,线程。sleep()/线程。wait()和除“synchronized”之外的编码相关关键字。此外,如果需要,可以按照正确的顺序将任务交给执行者。这是为了研究,所以可以随意使用Java1.6甚至1.7结构

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


共 (3) 个答案

  1. # 1 楼答案

    以正确的顺序返回结果是微不足道的。当每个结果到达时,将其存储在arraylist中,一旦获得所有结果,只需对arraylist进行排序。您可以使用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...
    
  2. # 2 楼答案

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

    声明一个“WorkItem”类,该类包含一个字节数组及其序号,以便它们可以按序号排序

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

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

    主线程等待锁定对象,然后如果队列中有项目,并且如果队列中第一个项目的序号(偷看,而不是出列)等于到目前为止处理的项目数,那么它将出列该项目并对其进行处理。如果没有,它会一直等待。如果所有项目都已生产和加工完毕,就完成了

  3. # 3 楼答案

    使用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()将准备就绪