2

在我当前的项目中,我试图在 Java 中复制以下功能,但我不确定这部分代码到底在做什么。

// This is C# code
if (numberOfMessages < 10)
{
     // just do it inline it's less expensive than spinning threads
     ReceiveTask(ct, numberOfMessages);
}
else
{
     // use the default partitioner to determine the number of tasks
     Parallel.ForEach(Partitioner.Create(0, numberOfMessages),
           (range) => ReceiveTask(ct, range.Item2 - range.Item1));
}

根据我对评论的分析,我认为当消息数大于 10 时,代码使用 C# 的 Partitioner 函数创建多个线程,其中接收到的消息数在线程之间“平均”分配。

此外,在此方法的后面部分中,注释引用了从 RecieveTask 接收到的消息,这些消息存储在红黑树中。RecieveTask 方法的评估没有揭示这种排序的任何实现,这引出了 Partitioner 是否也这样做的问题。

有人可以确认或更正我对 C# Partitioner 功能的理解,并给我一些关于如何在 Java 中完成此任务的想法吗?我对 Java 并发库的经验是有限的,我没有看到这样的选项可用。

编辑1:

我找到了排序的来源,RecieveTask 将消息添加到 SortedSet。

编辑2:

似乎分区器只是将任务分成组,但创建多个线程的是 Parallel 函数。

如果我按照评论中的建议调用 Java 的 ForkJoinPool,这种分区会自动发生,还是我需要自己划分工作?

如果我必须划分工作量,我将如何调用具有可变消息范围的 FutureTask 的多个实例?

4

1 回答 1

0

我的建议是你自己分工。

当谈到线程和并行计算时,没有什么魔力。所有漂亮而整洁的格式都伴随着价格——只要你意识到它或者它隐藏在实现代码的某个地方。

由于您正在创建的线程数量的不确定性,动态分叉线程在我看来并不是一个好主意,而且线程本身就是占用资源的对象。如果你在做一些工业项目。我建议使用线程池,在 Java 中是 ExecutorService。然后,如果您不关心执行顺序,您可以随意调用 ExecutorService.invokeAll()。

Java 中等价的红黑树是 TreeSet/TreeMap,它可以通过调用 headSet()、trailSet() 和 subSet() 方法自然地为您提供它的一个子集。因此,您可能会在这里进行少量编码,但在我看来,无论是编码风格还是性能,一切都非常简单和整洁。

于 2013-07-04T04:19:01.250 回答