CASとアトミックリファレンスの深い理解

CASとアトミックリファレンスの深い理解

CASの1つの深い理解

CASとは

ublic class CASDemo {
    
    

    //CAS compareAndSet:比较并交换
    public static void main(String[] args) {
    
    
        AtomicInteger atomicInteger = new AtomicInteger(2020);

        // 期望、更新
        // public final boolean compareAndSet(int expect, int update)
        // 如果我期望的值达到了,那么就更新,否则,就不更新, CAS 是CPU的并发原语!
        // ============== 捣乱的线程 ==================
        System.out.println(atomicInteger.compareAndSet(2020,2021));
        System.out.println(atomicInteger.get());
        //atomicInteger.getAndIncrement();

        System.out.println(atomicInteger.compareAndSet(2021,2020));
        System.out.println(atomicInteger.get());
        // ============== 期望的线程 ==================
        System.out.println(atomicInteger.compareAndSet(2020,6666));
        System.out.println(atomicInteger.get());


    }
}

安全でないクラス

ここに画像の説明を挿入

上図の背後にあるワード操作メモリ

ここに画像の説明を挿入

CAS:現在の作業メモリーの値をメインメモリーの値と比較します。この値が予想される場合は、操作を実行します。そうでない場合は、ループを続けます。

短所:

1.サイクルには時間がかかります

2.共有変数のアトミック性を保証できるのは1回だけです

3.ABA問題

CAS:ABA問題(王子のためのジャコウネコ)

ここに画像の説明を挿入

public class CASDemo {
    
    
    // CAS compareAndSet 比较并交换
    public static void main(String[] args) {
    
    
        AtomicInteger atomicInteger = new AtomicInteger(2020);

        // 期望、更新
        // public final boolean compareAndSet(int expect, int update)
        // 如果期望得值成功了,那么就更新,否则就不更新  CAS是CPU的并发原语。
        // ============== 捣乱的线程 ==================
        System.out.println(atomicInteger.compareAndSet(2020, 2021));
        System.out.println(atomicInteger.get());
        System.out.println(atomicInteger.compareAndSet(2021, 2020));
        System.out.println(atomicInteger.get());
        // ============== 期望的线程 ==================
        System.out.println(atomicInteger.compareAndSet(2020, 6666));
        System.out.println(atomicInteger.get());
    }
}

二、原子引用

ABA問題を解決し、アトミックリファレンスを導入してください!対応する考え:楽観的ロック!

バージョン番号によるアトミック操作!

public class CASDemo {
    
    
    // AtomicStampedReference 注意,如果泛型是一个包装类,注意对象的引用问题,范围内用同一个,超出自动new新的
	// 正常在业务操作,这里面比较的都是一个个对象
    static AtomicStampedReference<Integer> atomicStampedReference = new
            AtomicStampedReference<>(1, 1);

    // CAS compareAndSet : 比较并交换!
    public static void main(String[] args) {
    
    
        new Thread(() -> {
    
    
            int stamp = atomicStampedReference.getStamp(); // 获得版本号
            System.out.println("a1=>" + stamp);
            try {
    
    
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            atomicStampedReference.compareAndSet(1, 2,
                    atomicStampedReference.getStamp(),
                    atomicStampedReference.getStamp() + 1);
            System.out.println("a2=>" + atomicStampedReference.getStamp());
            System.out.println(atomicStampedReference.compareAndSet(2, 1,
                    atomicStampedReference.getStamp(),
                    atomicStampedReference.getStamp() + 1));
            System.out.println("a3=>" + atomicStampedReference.getStamp());
        }, "a").start();
		// 乐观锁的原理相同!
        new Thread(() -> {
    
    
            int stamp = atomicStampedReference.getStamp(); // 获得版本号
            System.out.println("b1=>" + stamp);
            try {
    
    
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            System.out.println(atomicStampedReference.compareAndSet(1, 6,
                    stamp, stamp + 1));
            System.out.println("b2=>" + atomicStampedReference.getStamp());
        }, "b").start();
    }
}

注意:

整数はオブジェクトキャッシュメカニズムを使用します。デフォルトの範囲は-128〜127です。valueOfはキャッシュを使用し、newは確実に新しいオブジェクトを作成し、新しいメモリを割り当てるため、newではなく静的ファクトリメソッドvalueOfを使用してオブジェクトインスタンスを取得することをお勧めします。スペース;
ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/qq_43803285/article/details/115387418