java “number++” 的原子性操作问题。
问各位一个问题:
例如:
private static int number=0;
public static void add(){
number++;
}
private static final int MAX_COUNT=10;
public static void main(String [] args){
Thread [] threads=new Thread[MAX_COUNT];
for(Thread t:threads){
t=new Thread(new Runnable() {
public void run() {
for(int i=0;i<100;i++){
add();
}
}
});
t.start();
}
while(Thread.activeCount()>1)Thread.yield();
System.out.println(number);
}
由于没有使用同步 所以在同时运行add()方法的线程可能会不止一个,
然则number++的操作并非原子操作:
在使用javap 之后看到其对应的指令为:
//静态成员number压入操作数堆栈
0: getstatic #13 // Field number:I
//创建一个临时变量
3: iconst_1
4: iadd
//静态成员number出栈放到常量解析池
5: putstatic #13 // Field number:I
由此我的看法是 “number++” 有四条指令,一定不会是一个原子性操作(一条指令都未必是原子性操作...)
一个方法中多个线程都在操作,并且没法保证修改变量操作的原子性.那么为什么每次都还能得到正确的值呢?
莫非是编译时候有过优化?
------解决方案--------------------
不是每次都能得到正确的值的!也许你进行了多次尝试还是得到同一个结果,主要是一个线程的加法操作只进行了一百次。你把循环次数弄到10000就可以看到明显的结果差异了。原因:新的线程创建完成前,100次的加法操作已经完成了。但不是每次都可以,可能在进行加法的时候该线程失去了控制权,这时你就有可能看到其他结果。