为什么局部变量不允许使用 volatile 关键字?

Why is volatile keyword not allowed for local variables?

考虑片段:

如果在主线程中,我在 方法 -

中有这个
volatile CountDownLatch latch = new CountDownLatch(3);

new Thread(new ProcessThread("Worker1",latch, 20000)).start();//20 secs
new Thread(new ProcessThread("Worker2",latch, 60000)).start();//60 secs
new Thread(new ProcessThread("Worker3",latch, 40000)).start();//40 secs

我看到 volatile 显示为非法修饰符。并且只允许 final并最终保证初始化安全

public static class ProcessThread implements Runnable {
  final CountDownLatch latch;
  final long workDuration;
  final String name;

  public ProcessThread(String name, CountDownLatch latch, long duration){
      this.name= name;
      this.latch = latch;
      this.workDuration = duration;
  }
}

下面的对象即 new CountDownLatch(3) 已正确构造,但我还想确保分配给上述对象的引用 latch 保证对其下面的代码可见。

final CountDownLatch latch = new CountDownLatch(3);

以上代码是否保证初始化,以便 latch 对下面的代码完全可见,即

new Thread(new ProcessThread("Worker1",latch, 20000)).start();

局部变量存在于栈中;当然,当您两次调用 same 方法时,它们的局部变量 all 在各自的堆栈上。

volatile 仅在 多个 线程写入 same 内存位置时才有意义(在堆上)。

这对于方法体内的局部变量完全没有意义!

And final guarantees initialization safety.

不适用于局部变量:它只会阻止您重新分配该变量。

final CountDownLatch latch = new CountDownLatch(3);

Does the above code will guarantee initialization so that latch is perfectly visible to the code below i.e

没有。正是这段代码保证了它:

public static class ProcessThread implements Runnable {

    final CountDownLatch latch;

    // Plus the assignment in the constructor.

}
一旦构造函数完成(通常),

final 字段保证可见。来自 JLS Sec 17.5:

An object is considered to be completely initialized when its constructor finishes. A thread that can only see a reference to an object after that object has been completely initialized is guaranteed to see the correctly initialized values for that object's final fields.

您在本地执行的操作不会有其他线程的可见性或干扰问题,因此声明局部变量 volatile 没有意义。