我正在制作一个分发任务的程序。我有像这样的传播者对象的arraylist:
ArrayList<Workers>
我正在通过一个文件,将其分成固定大小的块并发送给各种工人。我正在使用迭代器将块传递给工作者。通常有比工人更多的块,所以我需要在我的工人周围和周围循环。我如何做到这一点,我目前的解决方案使用像这样的迭代器。
private Worker getNextWorker() {
if (workerIterator == null)
workerIterator = workers.iterator();
if (!workerIterator.hasNext())
workerIterator = workers.iterator();
return workerIterator.next();
}
我同步了方法以及修改arraylist的方法但是这并不安全,因为另一个线程可以进入并修改迭代器调用之间的集合。因此,我同步整个文件拆分过程,使其成为一个大的原子语句。
1)我错过了什么吗?
2)是否有另一种,也许是更好的方式,我可以循环功能。
答案 0 :(得分:2)
我建议您不要重新发明轮子,并将BlockingQueue
与ThreadPoolExecutor
结合用于此目的。
答案 1 :(得分:1)
您可以启动工作线程(没有执行程序),并从有界阻塞队列中获取take
个元素。在您读取文件时,队列中有put
个块。当队列已满时,对put
的调用将阻塞,直到工作人员从队列中获取一个任务。如果队列为空,则工作人员将等待任务进入队列。完成处理后,您可以interrupt
工作线程。
或者,您可以将ThreadPoolExecutor
与bounded blocking queue和CallerRunsPolicy
一起使用。这样,如果队列未满,则将提交任务以执行。如果队列已满,则调用者线程将执行该任务(这为工作者提供了处理时间)。使用这种方法,您将拥有最多number_of_threads+queue_capacity
块,但在主线程处理时,某些工作线程可能处于空闲状态。