【詳解】Java併發之AtomicxxxFieldUpdater

引出

由於原子性的類型是後期引出的,但是想讓原來已經寫好的屬性也具有原子性,就可以利用這個類

AtomicXXXFieldUpdater主要包括以下幾個:AtomicIntegerFieldUpdaterAtomicLongFieldUpdaterAtomicReferenceFieldUpdater

要求

  • 字段必須是volatile類型的,在線程之間共享變量時保證立即可見
  • 字段的描述類型(修飾符public/protected/default/private)是與調用者與操作對象字段的關係一致。也就是說調用者能夠直接操作對象字段,那麼就可以反射進行原子操作。
  • 對於父類的字段,子類是不能直接操作的,儘管子類可以訪問父類的字段。
  • 只能是實例變量,不能是類變量,也就是說不能加static關鍵字。
  • 只能是可修改變量,不能使final變量,因爲final的語義就是不可修改。
  • 對於AtomicIntegerFieldUpdater和AtomicLongFieldUpdater只能修改int/long類型的字段,不能修改其包裝類型(Integer/Long)。如果要修改包裝類型就需要使用AtomicReferenceFieldUpdater

舉例使用

public class AtomicXXXFieldUpdater {



    public static void main(String[] args) throws InterruptedException {
        TestMe testMe = new TestMe();
        Set<Integer> data = new HashSet<>();
        for (int i = 0; i < 3; i++) {
            Thread thread = new Thread(() -> {
                for (int j = 0; j < 500; j++) {
                    testMe.updateNum();
                }
            });
            thread.start();
            thread.join();
        }
        System.out.println(data.size());

    }


}
class TestMe {


    private volatile int num = 0;

    public void updateNum(){
        AtomicIntegerFieldUpdater updaterNum = AtomicIntegerFieldUpdater.newUpdater(getClass(),"num");
        int i = updaterNum.incrementAndGet(this);
        System.out.println(i);
    }
}

使用場景總結

1. 想讓其他的類的屬性具備原子性

2. 不想使用任何鎖

3.大量需要原子類型修飾的對象,相比較會消耗內存

  • 如果直接使用原子類型修飾,需要包裝所有的數據
  • 但是通過Updater更新,只需要每次更新其中一個數據
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章