我已经实现了一个java代码来执行传入的任务(如Runnable
) 具有基于 hashCode 模块的 n 个线程nThreads
。理想情况下,工作应该在这些线程之间均匀地分布。
具体来说,我们有一个dispatchId
作为每个任务的字符串。
这是这个java代码片段:
int nThreads = Runtime.getRuntime().availableProcessors(); // Number of threads
Worker[] workers = new Worker[nThreads]; // Those threads, Worker is just a thread class that can run incoming tasks
...
Worker getWorker(String dispatchId) { // Get a thread for this Task
return workers[(dispatchId.hashCode() & Integer.MAX_VALUE) % nThreads];
}
重要的:在大多数情况下,dispatchId 是:
String dispatchId = 'SomePrefix' + counter.next()
但是,我担心 nThreads 的模除不是一个好的选择,因为 nThreads 应该是素数,以便更均匀地分布 dispatId 键。
对于如何更好地开展工作还有其他选择吗?
更新1:
每个Worker都有一个队列:Queue<RunnableWrapper> tasks = new ConcurrentLinkedQueue();
工作人员从中获取任务并执行它们。可以从其他线程将任务添加到此队列。
更新2:
任务相同dispatchId
可以多次出现,因此我们需要通过以下方式找到他们的线程dispatchId
.
最重要的是,每个工作线程必须顺序处理其传入的任务。因此,上面的更新1中就有了数据结构Queue。
更新3:此外,某些线程可能很忙,而另一些线程则空闲。因此,我们需要以某种方式将队列与线程解耦,但保持相同的 FIFO 顺序dispatchId
用于任务执行。
解决方案:我已经实现了 Ben Manes 的想法(他的答案如下),代码可以找到here https://github.com/vibneiro/dispatching.