原子性:哪些指令必须是不可分割的。在Java内存模型中,这些规则需声明仅适用于-—实例变量和静态变量,也包括数组元素,但不包括方法中的局部变量-—的内存单元的简单读写操作。
/**
* 非线程安全(原子性)
* @author Snway
*
*/
public class Atomicity {
private int value;
public int getNextValue() {
return value++; // 非原子操作(包含三个操作,即读取value,将value加1,并将计算结果写入value)
}
}
在Atomicity类中,如果执行时机不对,那么两个线程在调用getNextValue
时会得到相同的值。如图下所示,给出了这种错误情况。虽然递增运算value++看上去是单个操作,但事实上它包含三个独立的操作:读取value,将value+1,并将计算结果写入value。由于运行时可能将多个线程之间的操作交替执行,因此这两个线程可能同时执行读操作,从而使它们得到相同的值,并都将这个值加1.结果就是,在不同线程的调用中返回了相同的数值。
解决方法:
1、在声明方法getNextValue()加上锁,即public synchronized int getNextValue()
2、采用原子变量类,如:
public class Atomicity {
private AtomicInteger value = new AtomicInteger(0);
public int getNextValue() {
return value.incrementAndGet();
}
}
参考书籍:《Java并发编程实战》