与来自多个线程的数组(在Java中)的数组的非锁相互作用



我需要从两个线程访问的一系列字符串。它必须非常快速且线程安全。我宁愿不使用锁,我可以采用哪种方法来制作无锁的螺纹安全阵列?我需要Java中的食谱。

根据定义,唯一的线程安全写作是由竞争线程共享的内存的唯一可用的是由CPU中的原子指令提供的动作。这与Java并不相关(至少几乎始终几乎(,但是值得注意的是,在并发环境中没有锁定是可能的。

所以,这就是说,如果您想写入数组,则可能需要有锁。锁是解决一般问题的解决方案。

但是,只要它们只从数组中读取,您就可以愉快地在许多线程之间共享一个数组。因此,如果您的数组是不变的(或此事的任何其他对象(,则它将是线程安全的,因为从来没有机会进行争夺。

所以,假设您想从两个不同的线程中写入数组,但是您担心争夺。也许每个线程都希望录制大量数据。这个问题有几种不同的解决方案:我将尝试解释一些。这并不详尽,因为并发是一个很难解决的问题,尽管有一些共同的方法,但答案通常取决于特定情况。

  1. 最简单的方法

写入阵列时只需在数组上使用锁,看看它的性能即可。也许您实际上不需要现在担心性能问题。

  1. 使用生产者/消费者方法

而不是让两个线程写入同一数组,而是让每个线程"产生"值(也许将它们放在不同的线程安全队列上(,并让另一个线程负责"消耗"这些值(从队列中删除它们并将它们放在数组中(。

如果订单很重要,则该方法可能很难实现。但是您正在使用并发,因此无论如何订购都将是相当不确定性的。

  1. 批量写作

这里的想法是,您将要在其自己的临时批次值中存储要在每个线程中放入数组中的值。当批次达到足够大的尺寸时,线程将锁定数组并写入整个批次。

  1. 写入数组的分开部分

如果您知道数据的大小,则可以通过根本不允许线程写入相同的索引范围来避免争论。您将阵列除以线程数。当创建每个线程时,都会将开始索引到数组中。

此选项可能适合您要寻找的东西(无锁,线程安全(。

如何使用内置的Collections.synchronizedList

最新更新