天天看點

Atomic原子類-2

@[toc]

  • 上文我們介紹了Atomic原子類 并且寫了 AtomicInteeger 的使用 簡單的介紹了底層的實作 CAS
  • 本章我們介紹下 AtmoicArray 與 AtmoicReference
Atomic原子類-2

Atomic*Array 數組原子類

package com.yxl.modules.controller;

import java.util.concurrent.atomic.AtomicIntegerArray;

/**
 * 示範AtomicIntegerArray
 */
public class AtmoicArray {
    public static void main(String[] args) throws InterruptedException {
      AtomicIntegerArray atomicIntegerArray=new AtomicIntegerArray(1000);

        Decrement decrement = new Decrement(atomicIntegerArray);
        Increment increment = new Increment(atomicIntegerArray);


        Thread[] threads= new Thread[100];
        Thread[] threads2= new Thread[100];

        for (int i = 0; i < 100 ; i++) {
            threads2[i]=new Thread(decrement);
            threads[i]=new Thread(increment);
            threads2[i].start();
            threads[i].start();
        }

        for (int i = 0; i < 100 ; i++) {
            threads2[i].join();
            threads[i].join();
        }

        for (int i = 0; i <  atomicIntegerArray.length(); i++) {
            if(atomicIntegerArray.get(i)!=0) {
                System.out.println("發現非0值" + i);
            }
        }
        System.out.println("運作結束");

    }


}

class  Decrement implements Runnable{
    private  AtomicIntegerArray array;

    Decrement(AtomicIntegerArray array) {
        this.array = array;
    }

    @Override
    public void run() {
        for (int i = 0; i < array.length() ; i++) {
            array.getAndDecrement(i);
        }

    }
}

class  Increment implements Runnable{
    private  AtomicIntegerArray array;

    Increment(AtomicIntegerArray array) {
        this.array = array;
    }

    @Override
    public void run() {
        for (int i = 0; i < array.length() ; i++) {
            array.getAndIncrement(i);
        }

    }
}
           
  • 運作結果 ,會發現我們數組線程每次 加100 減100 ,并不會出現不等于0的資料,資料并沒有出現錯亂,AtomicIntegerArray 給我們提供了數組的原子性
    Atomic原子類-2

Atomic*Reference 引用類型原子類

Atomic*Reference 和我們之前講過的 AtomicInether 本質沒有任何差別,

AtomicInether 可以讓一個整形保證原子性

而AtomicReference可以讓對象保證原子性,

AtomicReference的用法肯定要比AtomicInether強,因為它一個對象可以包含多個屬性

Atomic原子類-2
  • 因為他是對象比較比較,所有不會有自增,自減操作,他會進行對象比較

    我們看下jdk 方法

Atomic原子類-2

把普通變量更新為原子變量

AtomicIntergerfiledUpdateer 對普通變量進行更新

  • 代碼示例
package com.yxzapp.aspect;

import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;

public class a implements  Runnable{

    static Persion persion;

    static Persion tom;

    //AtomicIntegerFieldUpdater的用法
    AtomicIntegerFieldUpdater<Persion > atomicIntegerFieldUpdater = AtomicIntegerFieldUpdater.newUpdater(Persion.class,"store");

    @Override
    public void run() {

        for (int i = 0; i < 10000 ; i++) {
            persion.store++;
            atomicIntegerFieldUpdater.getAndIncrement(tom);
        }

    }

    public static  class Persion{
            volatile int store;
        }


    public static void main(String[] args) throws InterruptedException {
        persion=new Persion();
        tom = new Persion();
        a a = new a();
        Thread thread = new Thread(a);
        Thread thread2 = new Thread(a);
        thread.start();
        thread2.start();
        thread.join();
        thread2.join();
        System.out.println("tom" + tom.store);
        System.out.println("persion " + persion.store);
    }


}
           
  • 運作結果
    Atomic原子類-2

但是使用AtomicIntergerfiledUpdateer 有幾點需要注意

  • 可見範圍
  • 不支援static 修飾的變量 否則會出現異常