如何在java中以线程安全的方式使迭代器循环

时间:2013-03-18 22:33:38

标签: java iterator concurrentmodification

我正在制作一个分发任务的程序。我有像这样的传播者对象的arraylist:

ArrayList<Workers>

我正在通过一个文件,将其分成固定大小的块并发送给各种工人。我正在使用迭代器将块传递给工作者。通常有比工人更多的块,所以我需要在我的工人周围和周围循环。我如何做到这一点,我目前的解决方案使用像这样的迭代器。

    private Worker getNextWorker() {
    if (workerIterator == null)
        workerIterator = workers.iterator();

    if (!workerIterator.hasNext())
        workerIterator = workers.iterator();

    return workerIterator.next();
}

我同步了方法以及修改arraylist的方法但是这并不安全,因为另一个线程可以进入并修改迭代器调用之间的集合。因此,我同步整个文件拆分过程,使其成为一个大的原子语句。

1)我错过了什么吗?

2)是否有另一种,也许是更好的方式,我可以循环功能。

2 个答案:

答案 0 :(得分:2)

我建议您不要重新发明轮子,并将BlockingQueueThreadPoolExecutor结合用于此目的。

答案 1 :(得分:1)

您可以启动工作线程(没有执行程序),并从有界阻塞队列中获取take个元素。在您读取文件时,队列中有put个块。当队列已满时,对put的调用将阻塞,直到工作人员从队列中获取一个任务。如果队列为空,则工作人员将等待任务进入队列。完成处理后,您可以interrupt工作线程。

或者,您可以将ThreadPoolExecutorbounded blocking queueCallerRunsPolicy一起使用。这样,如果队列未满,则将提交任务以执行。如果队列已满,则调用者线程将执行该任务(这为工作者提供了处理时间)。使用这种方法,您将拥有最多number_of_threads+queue_capacity块,但在主线程处理时,某些工作线程可能处于空闲状态。