gpt4 book ai didi

Java volatile 变量的行为不正确。

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:02:29 24 4
gpt4 key购买 nike

public class MyThread
{
volatile static int i;

public static class myT extends Thread
{
public void run ()
{
int j = 0;
while(j<1000000){
i++;
j++;
}
}
}

public static void main (String[] argv)
throws InterruptedException{
i = 0;

Thread my1 = new myT();
Thread my2 = new myT();
my1.start();
my2.start();

my1.join();
my2.join();

System.out.println("i = "+i);
}
}

由于 volatile 建立 happens-before 关系,所以 i 的最终值应该严格为 2000000。但是,实际结果与变量 i 没有 volatile 没有什么不同。谁能解释为什么它在这里不起作用?由于 i 被声明为 volatile,因此应该防止内存不一致。

最佳答案

Can anyone explanation why it doesn't work here? Since i is declared volatile, it should be protected from memory inconsistency.

它受到保护,但不幸的是 i++ 不是原子操作。它实际上是读取/增量/存储。所以 volatile 不会将您从线程间的竞争条件中解救出来。您可能会从您的程序中获得以下操作顺序:

  1. 线程 #1 读取 i,得到 10
  2. 紧接着,线程 #2 读取 i,得到 10
  3. 线程 #1 将 i 递增到 11
  4. 线程 #2 将 i 递增到 11
  5. 线程 #1 将 11 存储到 i
  6. 线程 #2 将 11 存储到 i

如您所见,即使发生了 2 次递增并且值已在线程之间正确同步,竞争条件意味着值只增加了 1。参见 nice looking explanation .这是另一个很好的答案:Is a volatile int in Java thread-safe?

您应该使用的是 AtomicInteger,它允许您从多个线程安全地递增。

static final AtomicInteger i = new AtomicInteger(0);
...
for (int j = 0; j<1000000; j++) {
i.incrementAndGet();
}

关于Java volatile 变量的行为不正确。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16289983/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com