AtomicInteger,這是java提供的一個原子操作Integer的類,這在我眼裏還是一個稀客,可能是不怎麼感興趣,以至於一直當作簡單的volatile,這也是我的拙見。其實這傢伙還是挺好用的,在常見的場景中,如count++或++count,這在java多線程的使用中是不安全的,而AtomicInteger屬於原子操作(線程安全),可以在下面的例子中看出來。
package org.jan.java.test;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
* 關於count++在多線程調用情況下
*
* @author jan
*/
public class Counter {
private volatile int count = 0;
/**
* 爲了保證數據的準確性,多線程的情況下需要加上synchronized關鍵字</br>
* 否則會出現出乎預料的結果 這也是線程安全的重要體現
*/
public void increment() {
count++;
}
private int getCount() {
return count;
}
/**
* 這裏模擬一個遞增的任務,遞增目標爲100W
*/
public static void main(String[] args) throws InterruptedException {
final Counter counter = new Counter();
// final AtomicCounter counter = new AtomicCounter();
int workCount = 1000000;
ExecutorService executor = Executors.newFixedThreadPool(10);
long start = System.currentTimeMillis();
for (int i = 0; i < workCount; i++) {
Runnable runnable = new Runnable() {
@Override
public void run() {
counter.increment();
}
};
executor.execute(runnable);
}
// 關閉啓動線程,執行未完成的任務
executor.shutdown();
// 等待所有線程完成任務,完成後才繼續執行下一步
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
System.out.println("耗時:" + (System.currentTimeMillis() - start) + "ms");
System.out.println("執行結果:count=" + counter.getCount());
}
}
它的結果不是我們預料的100 0000 .通常我們需要加上在count++時 加上synchronized關鍵字,保證他的正確性。
如果我們換個方式,用AtomicInteger來替換count++,怎麼做呢?
public class AtomicCounter {
private AtomicInteger count = new AtomicInteger(0);
// 使用AtomicInteger之後,不需要加鎖,也可以實現線程安全。
public void increment() {
//獲取當前的值並自增
count.incrementAndGet();
}
/**
* 獲取當前的值
* @return
*/
public int getCount() {
return count.get();
}
//遞減
public void deIncrement(){
count.decrementAndGet();
}
}
把最開始的代碼裏的Counter對象換成我們的AtomicCounter類的對象,試試他的方法,我們發現,結果就保證了100W!
AtomicInteger 還有其他的一些方法,查一下Api就行了。而且也不是說只有Integer有這麼個原子操作的類,這裏不是重點,有興趣就自己百度去吧。
//獲取當前的值
publicfinal int get()
//取當前的值,並設置新的值
publicfinal int getAndSet(intnewValue)
//獲取當前的值,並自增
publicfinal int getAndIncrement()
//獲取當前的值,並自減
publicfinal int getAndDecrement()
//獲取當前的值,並加上預期的值
publicfinal int getAndAdd(intdelta)
你說他就這麼一個特點,並不是很吸引人?
他的性能貌似也挺給力的,就如最開始的那個代碼把,我看了一下啊,在count++ 方法加上synchronized字段後與 atomicInteger的increment方法相比較,atomicInteger的性能貌似比前者更快!有興趣的可以自己比較一下看看。
嗯。
最後,感謝以下博文的鼎立奉獻,感謝百度祖師爺的全力幫助