多線程 原子通路
步驟 1 : 原子性操作概念
所謂的原子性操作即不可中斷的操作,比如指派操作
int i = 5;
原子性操作本身是線程安全的
但是 i++ 這個行為,事實上是有3個原子性操作組成的。
步驟 1. 取 i 的值
步驟 2. i + 1
步驟 3. 把新的值賦予i
這三個步驟,每一步都是一個原子操作,但是合在一起,就不是原子操作。就不是線程安全的。
換句話說,一個線程在步驟1 取i 的值結束後,還沒有來得及進行步驟2,另一個線程也可以取 i的值了。
這也是分析同步問題産生的原因 中的原理。
i++ ,i–, i = i+1 這些都是非原子性操作。
隻有int i = 1,這個指派操作是原子性的。
步驟 2 : AtomicInteger
JDK6 以後,新增加了一個包java.util.concurrent.atomic,裡面有各種原子類,比如AtomicInteger。
而AtomicInteger提供了各種自增,自減等方法,這些方法都是原子性的。 換句話說,自增方法 incrementAndGet 是線程安全的,同一個時間,隻有一個線程可以調用這個方法。
package multiplethread;
import java.util.concurrent.atomic.AtomicInteger;
public class TestThread {
public static void main(String[] args) throws InterruptedException {
AtomicInteger atomicI =new AtomicInteger();
int i = atomicI.decrementAndGet();
int j = atomicI.incrementAndGet();
int k = atomicI.addAndGet(3);
}
}
步驟 3 : 同步測試
分别使用基本變量的非原子性的**++運算符和 原子性的AtomicInteger對象的 incrementAndGet** 來進行多線程測試。
測試結果如圖所示

package multiplethread;
import java.util.concurrent.atomic.AtomicInteger;
public class TestThread {
private static int value = 0;
private static AtomicInteger atomicValue =new AtomicInteger();
public static void main(String[] args) {
int number = 100000;
Thread[] ts1 = new Thread[number];
for (int i = 0; i < number; i++) {
Thread t =new Thread(){
public void run(){
value++;
}
};
t.start();
ts1[i] = t;
}
//等待這些線程全部結束
for (Thread t : ts1) {
try {
t.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.printf("%d個線程進行value++後,value的值變成:%d%n", number,value);
Thread[] ts2 = new Thread[number];
for (int i = 0; i < number; i++) {
Thread t =new Thread(){
public void run(){
atomicValue.incrementAndGet();
}
};
t.start();
ts2[i] = t;
}
//等待這些線程全部結束
for (Thread t : ts2) {
try {
t.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.printf("%d個線程進行atomicValue.incrementAndGet();後,atomicValue的值變成:%d%n", number,atomicValue.intValue());
}
}
更多内容,點選了解: 多線程 原子通路