我需要从两个线程访问一个字符串数组。它必须非常快速且线程安全。我不想使用锁,我可以用什么方法来制作无锁的线程安全的字符串数组?我需要一个Java的食谱。
答案 0 :(得分:1)
根据定义,争用线程共享的内存可用的唯一线程安全写入是由CPU中的原子指令提供的操作。这与Java无关(至少,几乎所有时间),但值得注意的是,并发环境中没有锁的写入是可能的。
所以,这就是说,如果你想写入数组,你可能需要锁定。锁是解决一般问题的方法。
但是,只要它们只是从数组中读取,您就可以愉快地在多个线程之间共享数组而不会出现问题。因此,如果您的数组是不可变的(或者任何其他对象),那么由于没有争用的机会,它将是线程安全的。
所以,让我们假设你想从两个不同的线程写入数组,但是你担心争用。也许每个线程都想记录大量数据。这个问题有几种不同的解决方案:我将尝试解释一些问题。这并非详尽无遗,因为并发是一个难以解决的问题,虽然有一些常见的方法,但答案往往取决于具体情况。
在写入数组时,只需对数组使用锁定,看看它是如何执行的。也许你现在不需要担心性能问题。
不是让两个线程写入同一个数组,而是让每个线程都生成"值(可能将它们放在不同的线程安全队列中)并让另一个线程负责"消费"这些值(从队列中删除它们并将它们放入数组中)。
如果订单很重要,这种方法实施起来可能很棘手。但是你使用的是并发性,所以无论如何,排序都是非常不确定的。
这里的想法是,您要将每个线程中要放入数组的值存储在其自己的临时批量值中。当批次达到足够大的大小时,线程将锁定数组并写入整个批次。
如果您知道数据的大小,则可以通过简单地不允许线程写入相同的索引范围来避免争用。您将数组除以线程数。每个线程在创建时都会被赋予数组的起始索引。
此选项可能符合您的要求(无锁,线程安全)。
答案 1 :(得分:0)
如何使用内置的Collections.synchronizedList
?