如何以线程安全的方式迭代数组列表(Java)

时间:2017-02-06 19:02:46

标签: java multithreading concurrency

我有一个我在多线程应用程序中使用的数组列表,我想要一种方法以某种方式能够遍历数组,同时当我向列表添加元素时不会引发任何异常我在迭代。有没有办法在迭代时停止修改数组列表?

编辑: 我现在意识到我提交的问题非常糟糕,而且下来的选票是值得的。这是试图解决我的问题。

我想做的是有办法阻止'在我迭代之前的列表,以便我不会得到并发修改异常。问题是迭代将花费相当多的处理器时间来完成,因为列表将非常大,并且我希望对每个元素执行的操作将花费相当多的时间。如果我使用synchronized方法,这是一个问题,因为add方法会阻塞大量时间并降低应用程序性能。所以我要做的是创建一个模仿数组列表的类,除了当它被阻止',并且方法试图修改它时,它将存储该请求,当列表是'畅通'它将在一个单独的线程中执行所有请求。问题在于,当我尝试实现此策略时,我必须将请求存储在某种列表中,并遇到与之前相同的问题,因为必须阻止在请求线程中添加到请求列表的能力正在迭代请求。我对如何实施此解决方案感到茫然,或者即使它是正确的解决方案。如果有人能帮助我,我将非常感激。

1 个答案:

答案 0 :(得分:1)

您的选择是使用同步还是使用java.util.concurrent包中提供的实现。您还需要阅读有关该问题的信息。你问的是一个非常基本和经典的问题,关于这个问题有很多信息。但这里有你的基本选择:

  1. 使用同步 - veru昂贵的性能明智,但绝对是防弹。在synchronized术语中阅读或阅读Lock界面及其实现。另请参阅Semaphore课程。请注意,此选项会在您的表现中创造一个非常严重的瓶颈
  2. 正如其中一条评论所说使用CopyOnWriteArrayList类。还有一些缺点,但在大多数情况下是完全同步的更好选择。
  3. 在两个选项之间进行选择时,请考虑以下几点:如果正确完成同步化是一个防弹解决方案,那么这是一项非常繁琐的工作,需要进行大量的测试,这并非易事。所以这已经是一个很大的缺点。此外,在大多数情况下读取数量超过写入或数组大小足够小(比如说几百个元素),其中写入时的副本是可接受的。所以我猜大多数情况下CopyOnWriteArrayList都是首选。关键是在上述两个选项之间进行选择时没有明确的答案。程序员需要查看情况并选择更适合他/她的案例的选项