package com.hjr.back16.common.util; import static java.lang.System.out; /** * 自增操做原子性測試 * @author scuechjr * @date 2016-4-24 1:29:48 */ public class IncrementTestDemo { public static int count = 0; public static Counter counter = new Counter(); public static void main(String[] args) { for (int i = 0; i < 10; i++) { new Thread() { public void run() { for (int j = 0; j < 1000; j++) { count++; counter.increment(); } } }.start(); } try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } out.println("static count: " + count); out.println("Counter: " + counter.getValue()); } } class Counter { private int value; public synchronized int getValue() { return value; } public synchronized int increment() { return ++value; } public synchronized int decrement() { return --value; } }
代碼執行結果: java
static count: 9898 Counter: 10000
其中,Counter的increment方法添加了同步鎖,能夠保證原子操做。Counter的數值爲10000,說明count確實自增了10000次,若是自增是原子操做的話,count的值應該也是10000的,然而結果並非的。 編程
注意:可能有些同窗在跑的Demo時有可能跑出count等於10000,這是由於多線程沒有同時自增的狀況,多跑幾回就發現問題,或者在確認代碼沒有問題後,把count++這句代碼後邊的counter.increment()刪除後多跑幾回就能夠了。 安全
上邊的代碼太多,換個簡單的,java代碼: 多線程
package com.hjr.back16.common.util; /** * * @author scuechjr * @date 2016-4-24 1:56:27 */ public class TestDemo { public static int count; public void code() { count++; } }
code()方法對應字節碼以下: 測試
public void code(); flags: ACC_PUBLIC Code: stack=2, locals=1, args_size=1 0: getstatic #2 // Field count:I count++開始 3: iconst_1 4: iadd 5: putstatic #2 // Field count:I count++結束 8: return LineNumberTable: line 12: 0 line 13: 8如上字節碼,咱們發現自增操做包括取數(getstatic #2)、加一(iconst_1和iadd)、保存(putstatic #2),並非咱們認爲的一條機器指令搞定的。