[Java]初識AtomicInteger

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的性能貌似比前者更快!有興趣的可以自己比較一下看看。

嗯。

最後,感謝以下博文的鼎立奉獻,感謝百度祖師爺的全力幫助

  1. http://my.oschina.net/i33/blog/50503
  2. http://blog.csdn.net/zz198808/article/details/8029405


發佈了70 篇原創文章 · 獲贊 36 · 訪問量 22萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章