AtomicStampedReference AtomicReference解決CAS機制中ABA問題


AtomicStampedReference AtomicReference解決CAS機制中ABA問題

AtomicStampedReference

AtomicStampedReference它內部不僅維護了對象值,還維護了一個版本號(可以是任何一個整數,它使用整數來表示狀態值)。當AtomicStampedReference對應的數值被修改時,除了更新數據本身外,還必須要更新版本號。因此只要版本號發生變化,就能防止不恰當的寫入。版本號類似於時間戳。

import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicStampedReference;

public class Test {
    /** 
    **/

    public static void main(String[] args) {
        AtomicInteger integer = new AtomicInteger(0);
        AtomicStampedReference<Integer> reference = new AtomicStampedReference<>(100,1000);
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                integer.compareAndSet(0,1);
                integer.compareAndSet(1,0);
            }
        });
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.currentThread().sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                boolean b = integer.compareAndSet(0, 1);
                System.out.println("AtomicInteger替換");
                if(b) System.out.println("0已經被替換為1");
                else System.out.println("替換失敗");
            }
        });
        Thread t3 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.currentThread().sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                reference.compareAndSet(100,-100,
                        reference.getStamp(), reference.getStamp()+1);
                reference.compareAndSet(-100,100,
                        reference.getStamp(), reference.getStamp()+1);
            }
        });
        Thread t4 = new Thread(new Runnable() {
            @Override
            public void run() {
                int stamp = reference.getStamp();
                try {
                    Thread.currentThread().sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                boolean b = reference.compareAndSet(100, -100,
                        stamp, reference.getStamp() + 1);
                System.out.println("AtomicStampedReference替換");
                if(b) System.out.println("100已經被替換為-100");
                else System.out.println("替換失敗");
            }
        });
        t1.start();
        t2.start();
        t3.start();
        t4.start();
    }
}
輸出結果:
AtomicInteger替換
0已經被替換為1
AtomicStampedReference替換
替換失敗

AtomicReference

AtomicReference類提供了一個可以原子讀寫的對象引用變量。 原子意味着嘗試更改相同AtomicReference的多個線程(例如,使用比較和交換操作)不會使AtomicReference最終達到不一致的狀態。

import java.util.concurrent.atomic.AtomicReference;

public class ABAObjectTest {
    public static void main(String[] args) {
        SubObject subObject = new SubObject(100,"一百");
        AtomicReference<SubObject> reference = new AtomicReference<>(subObject);
        SubObject subObject1 = new SubObject(200,"二百");
        SubObject subObject2 = new SubObject(300,"三百");

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                boolean b = reference.compareAndSet(subObject, subObject1);
                SubObject object = reference.get();
                System.out.println(b);
                System.out.println(object);
            }
        });
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.currentThread().sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("=============");
                System.out.println(reference.get());
                boolean b = reference.compareAndSet(subObject, subObject2);
                System.out.println(b);
                System.out.println(reference.get());
            }
        });
        t1.start();
        t2.start();
    }
}
        /*輸出結果:
        true
        SubObject{intNum=200, string='二百'}
        =============
        SubObject{intNum=200, string='二百'}
        false
        SubObject{intNum=200, string='二百'}*/

class SubObject {
    public int intNum;
    public String string;

    public int getIntNum() {
        return intNum;
    }

    public void setIntNum(int intNum) {
        this.intNum = intNum;
    }

    public String getString() {
        return string;
    }

    public void setString(String string) {
        this.string = string;
    }

    public SubObject(int intNum, String string) {
        this.intNum = intNum;
        this.string = string;
    }

    public SubObject() {
    }

    @Override
    public String toString() {
        return "SubObject{" +
                "intNum=" + intNum +
                ", string='" + string + '\'' +
                '}';
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM