为什么局部变量不允许使用 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 没有意义。
考虑片段:
如果在主线程中,我在 方法 -
中有这个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 没有意义。