什么动作清除线程本地缓存?



考虑这个来自GeeksForGeeks的例子:

public class VolatileKeyword {
private static final Logger LOGGER = Logger.getLogger(VolatileKeyword.class);
private static int MY_INT = 0;
public static void main(String[] args) {
new ChangeListener().start();
new ChangeMaker().start();
}
static class ChangeListener extends Thread {
@Override public void run() {
int local_value = MY_INT;
while (local_value < 5) {
// (A)
if (local_value != MY_INT) {
LOGGER.info("Got Change for MY_INT : " + MY_INT);
local_value = MY_INT;
}
}
}
}
static class ChangeMaker extends Thread {
@Override public void run() {
int local_value = MY_INT;
while (MY_INT < 5) {
LOGGER.log(Level.INFO, "Incrementing MY_INT to " + (local_value + 1));
MY_INT = ++local_value;
try {
Thread.sleep(500);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
如本文所述,您看到的输出始终是:
Incrementing MY_INT to 1
Incrementing MY_INT to 2
Incrementing MY_INT to 3
Incrementing MY_INT to 4
Incrementing MY_INT to 5

这是由于ChangeListener总是从其线程本地缓存中读取MY_INT。(我测试了一下以确定)。

但是,如果您要用以下任何内容替换// (A):

  • Thread.currentThread().isAlive();
  • Thread.sleep(0)
  • Thread.interrupted()
  • System.out.print("");
  • volatile整数x添加到ChangeListener,并将// (A)替换为x += MY_INT

除其他事项外,您将获得与将MY_INT设置为volatile变量相同的输出。也就是说,

Incrementing MY_INT to 1
Got Change for MY_INT : 1
Incrementing MY_INT to 2
Got Change for MY_INT : 2
Incrementing MY_INT to 3
Got Change for MY_INT : 3
Incrementing MY_INT to 4
Got Change for MY_INT : 4
Incrementing MY_INT to 5
Got Change for MY_INT : 5

我上面列出的导致线程缓存被清除的操作的共同点是什么?

编辑:最后两个建议显然针对易失性或同步代码,导致"缓存重置",但其他建议呢?

我猜…这是一个竞争条件。这意味着当两个线程试图访问某个变量时,它将其缓存到以下几个操作中,以使其操作更快。为了避免这种情况,您可以使用AtomicInteger类,当您检索基于内存中当前值的整数时,它是线程安全的。检查https://www.tutorialspoint.com/java_concurrency/concurrency_atomic_integer.htm

相关内容

  • 没有找到相关文章

最新更新