volatile與AtomicIntegerfieldupdater 區別與關係
volatile 實現了多執行緒的可見性,用於多執行緒對某個變數的修改 比如bool 值的變化,別的執行緒立即看到,可以退出迴圈之類的後續操作
但是volatile 不是執行緒安全,對其修飾的變數++ 加法減法等操作 保證不了執行緒安全
而AtomicIntegerfieldupdater 實現了普通變數的原子操作 ,加法減都可以
下面給出一個書上的例子,裡面對AtomicIntegerfieldupdater結果進行驗證 驗證藉助了 AtomicInteger,
下面這個例子 說明AtomicIntegerfieldupdater 可以操作物件裡面的屬性,AtomicInteger 只能操作單個的普通變數
下面轉載一個對其理解
對已經new出來的某個變數進行修改,保證其原子性。
AtomicIntegerFieldUpdater使用最重要的在於其建構函式,我們可以在其api檔案中檢視
public static <U> AtomicIntegerFieldUpdater<U>newUpdater(Class<U> tclass,
String fieldName)
使用方法:
private AtomicIntegerFieldUpdater
atomicIntegerFieldUpdater = AtomicIntegerFieldUpdater.newUpdater(
Details.class, "numberTimesInvoked" );
詳細使用程式碼:
- import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
- /**
-
* volatiles cannot be used directly in operations that do x = x + 1 for
- * numbers can be skipped or duplicated when there are multiple threads
- * involved.
- * <p>
- * Hardware supports Atomic Compare And Swap operations. CAS java classes
- * like AtomicInteger can use this feature of the hardware to ensure that
- * a "x = x + 1" like operation is atomic.
- * <p>
- * However AtomicInteger is significantly more resource intensive than a simple
- * volatile. If there are many instances of a class which has an AtomicInteger
- * this increase in resource over a volatile can be significant.
- * <p>
- * The AtomicIntegerFieldUpdater comes to the rescue - it can be registered
- * with a volatile variable of a class and can then be used on multiple
- * instances of the class.
- *
- * If there are 1000s of instances of a class which would ordinarily have
- * AtomicInteger this can be a big saving.
- *
- * AtomicIntegerFieldUpdater is able to update a volatile field of an object
- * atomically.
- *
- * @author John Dickerson
- */
- publicclass AtomicIntegerFieldUpdaterCounter {
- // AtomicIntegerFieldUpdater is registered with Details.class so that it
- // knows it will later be updating the volatile field called
- // numberTimesInvoked
- //步驟1 構造方法
- private AtomicIntegerFieldUpdater<Details>
- atomicIntegerFieldUpdater = AtomicIntegerFieldUpdater.newUpdater(
- Details.class, "numberTimesInvoked" );
- /**
- * Diferent threads can call this method to update the volatile field of
- * an instance of Details
- *
- * @param details Details object which has the volatile field called
- * "numberTimesInvoked" in it.
- *
- * @return the value of the counter after it has been incremented by one
- */
- //步驟2 對AtomicIntegerFieldUpdater修飾的變數進行操作
- publicint addOne( Details details ){
- // performs a "x = x + 1" style atomic operation
- //return atomicIntegerFieldUpdater.addAndGet( details, 1 );
- returnthis.atomicIntegerFieldUpdater.getAndIncrement(details);
- }
- publicint subOne(Details details)
- {
- return atomicIntegerFieldUpdater.decrementAndGet(details);
- }
- /**
- * See test class for example of using this class with multiple threads,
- * some of which are writing to the volatile field and some which are
- * reading from the volatile field
- * @throws InterruptedException
- */
- publicstaticvoid main(String[] args) throws InterruptedException {
- final AtomicIntegerFieldUpdaterCounter atomicIntegerFieldUpdaterCounter =
- new AtomicIntegerFieldUpdaterCounter();
- // This call would ordinarily be made by many other threads
- final Details d=new Details();
- System.out.print("物件d的變數numberTimesInvoked累計前:"+d.getNumberTimesInvoked());
- System.out.println(",A累計前:"+TestAtomic.A);
- Thread t0= new Thread(
- new Runnable(){
- @Override
- publicvoid run() {
- for(int j=0;j<100000;j++)
- {
- atomicIntegerFieldUpdaterCounter.addOne(d);
- TestAtomic.A++;
- }
- }
- });
- Thread t1= new Thread(
- new Runnable(){
- @Override
- publicvoid run() {
- for(int j=0;j<100000;j++)
- {
- TestAtomic.A++;
- atomicIntegerFieldUpdaterCounter.subOne(d);
- }
- }
- });
- t0.start();
- t1.start();
- t0.join();
- t1.join();
- System.out.print("物件d的變數numberTimesInvoked累計後:"+d.getNumberTimesInvoked());
- System.out.println(",A累計後:"+TestAtomic.A);
- }
- }
- /**
- * @author John Dickerson
- */
- publicclass Details {
- volatileint numberTimesInvoked;
- publicint getNumberTimesInvoked() {
- return numberTimesInvoked;
- }
- publicvoid setNumberTimesInvoked(int numberTimesInvoked) {
- this.numberTimesInvoked = numberTimesInvoked;
- }
- }
執行結果如下:
物件d的變數numberTimesInvoked累計前:0,A累計前:0
物件d的變數numberTimesInvoked累計後:0,A累計後:199947
從上述程式碼中我們可以看出,新建立的:Details d=newDetails();物件d的變數numberTimesInvoked,經過this.atomicIntegerFieldUpdater.getAndIncrement(d); 構造後成了一個執行緒安全的變數。
http://blog.csdn.net/leixingbang1989/article/details/50496201