int 易失性?
Volatile for int?
在Java中volatile需要int类型吗?据我了解,32 位平台 read/write 4 字节类型的数据是原子的。如果我将在并发程序中使用 int 数据类型,我会遇到问题吗?
考虑以下代码:
class Demo {
int value;
void foo() {
while (value == 0);
System.out.println("Done!");
}
}
即使您将 value
更改为来自不同线程的某个非零值,也无法保证循环将永远完成。因为 value
不是原子的,所以循环可能被优化为(有效):
if (value == 0)
while (true);
因此,如果在首次调用 foo()
时 value
恰好为零,则会发生无限循环。
但是如果你做value
volatile
,这个优化就做不到了
volatile不是用于原子操作,而是为了可见性。如果进行了任何更改并且它应该对其他线程可见,则应使用 volatile。 Here is a short description by java tutorial:
Atomic actions cannot be interleaved, so they can be used without fear of thread interference. However, this does not eliminate all need to synchronize atomic actions, because memory consistency errors are still possible. Using volatile variables reduces the risk of memory consistency errors, because any write to a volatile variable establishes a happens-before relationship with subsequent reads of that same variable. This means that changes to a volatile variable are always visible to other threads. What's more, it also means that when a thread reads a volatile variable, it sees not just the latest change to the volatile, but also the side effects of the code that led up the change.
在Java中volatile需要int类型吗?据我了解,32 位平台 read/write 4 字节类型的数据是原子的。如果我将在并发程序中使用 int 数据类型,我会遇到问题吗?
考虑以下代码:
class Demo {
int value;
void foo() {
while (value == 0);
System.out.println("Done!");
}
}
即使您将 value
更改为来自不同线程的某个非零值,也无法保证循环将永远完成。因为 value
不是原子的,所以循环可能被优化为(有效):
if (value == 0)
while (true);
因此,如果在首次调用 foo()
时 value
恰好为零,则会发生无限循环。
但是如果你做value
volatile
,这个优化就做不到了
volatile不是用于原子操作,而是为了可见性。如果进行了任何更改并且它应该对其他线程可见,则应使用 volatile。 Here is a short description by java tutorial:
Atomic actions cannot be interleaved, so they can be used without fear of thread interference. However, this does not eliminate all need to synchronize atomic actions, because memory consistency errors are still possible. Using volatile variables reduces the risk of memory consistency errors, because any write to a volatile variable establishes a happens-before relationship with subsequent reads of that same variable. This means that changes to a volatile variable are always visible to other threads. What's more, it also means that when a thread reads a volatile variable, it sees not just the latest change to the volatile, but also the side effects of the code that led up the change.