最近刷到诸葛大神的关于Java 内存模型的视频,讲到volatile关键字可以保证并发编程的可见性,即变量在各线程内存一致性。
里面讲到个例子,创建十个线程,每个线程对静态变量进行 1000 次 加一操作, 到最后这个变量值应该是 10 * 1000 = 10000.
但是个人在编程的时候,发现实际的值不一定是 10000, 是 <= 10000 的数。
加了log调试也没发现问题。
下面是代码:
public class VolatileTestOnly {
//public static int num = 0;
public static volatile int num = 0;
public static void increase(){
num++;
}
public static void main(String args[]) throws InterruptedException {
System.out.println("main start - num = " + num);
Thread threads[] = new Thread[10];
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(new Runnable() {
@Override
public void run() {
for (int j = 0; j < 1000; j++) {
//num++;
increase();
//System.out.println("thread num: " + num);
}
}
});
threads[i].start();
}
System.out.println("before join num: " + num);
for (Thread t: threads) {
t.join();
}
System.out.println("end num: " + num);
}
}
随机一次的结果如下:
before join num: 1090
end num: 9708
后续更新, 只需对操作变量的地方加上同步锁即可
// 并发编程需三保证: 可见性、有序性、原子性
// volatile 保证可见性、有序性,但是不保证原子性,需使用synchronized 关键配合
public synchronized static void increase() {
num++;
}