【发布时间】:2019-04-23 14:08:20
【问题描述】:
我正在尝试编写处理器密集型任务,因此我想使用多线程并在可用处理器内核之间共享计算。
假设我有数千次迭代,所有迭代都有两个阶段:
- 扫描数十万个选项的一些工作线程 而他们必须从共享数组(或其他一些数据结构)中读取数据,而不会修改数据。
- 一个线程收集所有工作线程的结果(同时 他们正在等待)并对共享数组进行修改
这些阶段是按顺序排列的,因此没有重叠(没有同时写入和读取数据)。我的问题是:如何确保在下一个阶段(阶段 1)开始之前为工作线程更新数据(缓存)。
我假设当人们在这种情况下谈论缓存或缓存时,他们指的是处理器缓存(如果我错了,请纠正我)。
据我了解,volatile 只能用于非引用类型,而使用同步没有意义,因为工作线程在读取时会相互阻塞(处理选项时可能会有数千次读取)。
在这种情况下我还能使用什么?
现在我有一些想法,但我不知道它们的成本有多大(很可能是):
为所有迭代创建新的工作线程
在新的迭代开始之前,在同步块中为每个线程复制数组(最大可达到 195kB)
我对 ReentrantReadWriteLock 很感兴趣,但我不明白它与缓存有何关系。读取锁获取是否可以强制读取器的缓存更新?
【问题讨论】:
-
“我的问题是,如何确保在下一阶段 1 开始之前为工作线程更新数据(缓存)。” - 通常,您会等待执行更新的线程完成,然后开始另一个阶段 1。例如,您可以使用join method 来执行此操作。如果您还没有通读Java Tutorial on Concurrency,我建议您从那里开始。
-
谢谢!教程结束了,刚刚。适合审查,但没有什么新东西。我知道如何同步线程,只是不知道如何保持内存一致性。如果我使数组易失,我假设它适用于引用而不是存储在数组中的数据。意味着我不知道存储在数组中的数据的任何更改是否对所有线程都是可见的。在我将数组处理为不可变的情况下,易失性会有所帮助,但我仍然必须在所有迭代之前制作价值 195kB 的数据的副本。或者我误解了一些非常糟糕的东西......
标签: java multithreading cpu-cache