我们知道在Java中,直到声明为volatile之前,long和double类型的赋值都不是原子性操作。我的问题是,在我们的编程实践中这究竟有多重要。
例如,如果您看下面的类,它们的对象被多个线程共享。
现在考虑另一个SharedLong。
现在我们可以看到上述两个版本都不是线程安全的。对于
在这两种情况下,如果一个实例不被多个线程共享,则类是安全的。
要使上述类线程安全,我们需要声明 int 和 long 都是 volatile 或使方法同步。
这让我想知道:在我们正常编程过程中,如果对
/**
* The below class is not thread safe. the assignments to int values would be
* atomic but at the same time it not guaranteed that changes would be visible to
* other threads.
**/
public final class SharedInt {
private int value;
public void setValue(int value) {
this.value = value;
}
public int getValue() {
return this.value;
}
}
现在考虑另一个SharedLong。
/**
* The below class is not thread safe because here the assignments to long
* are not atomic as well as changes are not
* guaranteed to be visible to other threads.
*/
public final class SharedLong {
private long value;
public void setValue(long value) {
this.value = value;
}
public long getValue() {
return this.values;
}
}
现在我们可以看到上述两个版本都不是线程安全的。对于
int
,因为线程可能会看到整数的旧值。而在 long
的情况下,它们可以看到 long 变量的损坏以及旧值。在这两种情况下,如果一个实例不被多个线程共享,则类是安全的。
要使上述类线程安全,我们需要声明 int 和 long 都是 volatile 或使方法同步。
这让我想知道:在我们正常编程过程中,如果对
long
和double
赋值不是原子操作,那么它真的很重要吗? 因为这两个变量都需要声明为volatile或用于多线程访问的 synchronized,所以我的问题是:在哪些情况下,long赋值不是原子操作可能会有影响?