Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/366.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在java中以线程安全的方式使迭代器循环_Java_Iterator_Concurrentmodification - Fatal编程技术网

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

如何在java中以线程安全的方式使迭代器循环,java,iterator,concurrentmodification,Java,Iterator,Concurrentmodification,我正在制作一个分配任务的程序。我有如下通信器对象的arraylist: ArrayList<Workers> 我同步了方法以及修改arraylist的方法,但是这并不安全,因为另一个线程可以进来并在迭代器调用之间修改集合。因此,我同步了整个文件拆分过程,使其成为一个大的原子语句 1) 我错过什么了吗 2) 有没有另一种可能更好的方法可以实现这种循环功能。我建议您不要重新发明轮子,并将阻塞队列与线程池执行器结合使用。您可以启动workers线程(无执行器),并让他们从有界阻塞队列中获

我正在制作一个分配任务的程序。我有如下通信器对象的arraylist:

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

1) 我错过什么了吗


2) 有没有另一种可能更好的方法可以实现这种循环功能。

我建议您不要重新发明轮子,并将
阻塞队列
线程池执行器
结合使用。

您可以启动workers线程(无执行器),并让他们
从有界阻塞队列中获取
元素。读取文件时,将
块放入队列中。当队列已满时,对
put
的调用将被阻止,直到工作人员从队列中执行一项任务为止。如果队列为空,工作人员将等待任务放入队列。处理完成后,您可以中断工作线程


或者,您可以将a与和
调用方策略一起使用。这样,如果队列未满,任务将提交执行。如果队列已满,则调用线程将执行任务(这将给工作线程留出处理时间)。使用这种方法,您最多将拥有
线程数+队列容量
块,但某些工作线程在主线程处理时可能处于空闲状态。

您最好让工作线程执行任务,而不是将任务交给工作线程。也就是说,在JDK中有几种预先存在的解决方案可以用于这类事情:
Executors
ExecutorService
CompletionService
…为什么不使用ExecutorService?问题是我处理的文件很大,而我将文件分成块的原因是为了避免内存问题。然而,如果我能以某种方式限制工作池的大小,并阻止更多的工作进入,直到工人拿出一些东西,这将是完美的。这是可能的吗?谢谢,我会研究一下,我想这一定存在。我该如何使用阻塞队列来实现这一点,我能想到的一种方法是让工作人员在队列中,我取出一个,读取文件块,发送,然后将该工作人员放在队列的后面。这不是设计模式的实际运行方式,但它可能会工作??您应该将文件块放入队列中,并通过Executor进行处理。谢谢,我现在开始意识到:)一个问题,我将从上面开始回答:问题是我处理的文件很大,而我将文件分成块的原因是为了避免内存问题。然而,如果我能以某种方式限制工作池的大小,并阻止更多的工作进入,直到工人拿出一些东西,这将是完美的。这有可能吗?是的,有可能。您的队列将以一定的容量创建,因此队列中只有一部分文件,而其他部分将等待处理。您可以查看
    private Worker getNextWorker() {
    if (workerIterator == null)
        workerIterator = workers.iterator();

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

    return workerIterator.next();
}