最近在工作中和一個同事因為自增是不是原子性操作爭論的面紅耳赤,那Java的自增操作到底是不是原子性操作呢,答案是否的,即Java的自增操作不是原子性操作。
1.首先我們先看看Bruce Eckel是怎麼說的:
In the JVM an increment is not atomic and involves both a read and a write. (via the latest Java Performance Tuning Newsletter)
意思很簡單,就是說在jvm中自增不是原子性操作,它包含一個讀操作和一個寫操作。
2.以上可能還不能讓你信服,要想讓人心服口服,就必須用代碼說話。正如FaceBook的文化一樣:代碼贏得爭論。那我們就看一段代碼:
以下的代碼是用100個線程同時執行自增操作,每個線程自增100次,如果自增操作是原子性操作的話,那麼執行完amount的值為10,000。運行代碼之後,你會發現amount的值小於10,000,這就說明自增操作不是原子性的
/**
*
* @author renrun.wu
*/
public class MultiThread implements Runnable {
private int count;
private int amount = 1;
public MultiThread() {
count = 100;
}
public MultiThread(int count) {
this.count = count;
}
@Override
public void run() {
for (int i = 0; i < count; i++) {
amount++;
}
}
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
MultiThread multiThread =new MultiThread();
for (int i = 0; i < 100; i++) {
executorService.execute(multiThread);
}
executorService.shutdown();
try {
Thread.sleep(60000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(multiThread.amount);
}
}