假设我们有一个包含两个元素的数组,这些元素是一些原始值的类型。
volatile int[] a = new int[2]{0,0};
我有两个线程,每个线程都写入/读取其中一个元素。 第一个主题仅与[0],第二个主题仅与[1]。
即使不同的索引值受到影响,数组也能以这种方式工作,或者数组仍然需要锁定吗?
答案 0 :(得分:4)
线程不需要在任何其他线程未使用的内存位置上发出锁定。因此,在您的情况下,不需要lock
语句。
话虽这么说,你应该担心CPU缓存锁定。如果a[0]
和a[1]
都在同一个64字节的块中,它们将共享cache line,这意味着每个CPU核心都会尝试将该内存块加载到板载缓存中,锁定任何其他CPU核心。如果发生这种情况,只有一个线程可以一次访问这些变量,并且任何其他线程将阻塞,直到缓存被推回到主存储器并释放锁定。这个问题称为false sharing,会限制您的性能,使多线程方法的性能不比单线程解决方案好,甚至可能更差。没有办法关闭这个锁,虽然你可以通过将变量与内存间隔开来避免它,因此它们属于不同的64字节块。
(64字节基于现代Wintel ......您的体验可能会有所不同)