【高併發】03 原子性 Atomic包

一 Atomic包

1、CAS Unsafe.compareAndSwapInt

2、AtomicLong LongAdder

3、AtomicReference 、AtomicReferenceFieldUpdater

package com.current.flame.test;

import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @author haoxiansheng
 */
@Slf4j
public class AtomicExample1 {
    private static AtomicReference<Integer> count =  new AtomicReference<>(0);

    @Getter
    private volatile int sum = 100;

    // 更新的必須由volatile關鍵字修飾 不能用static修飾(ExceptionInInitializerError)
    private static AtomicIntegerFieldUpdater<AtomicExample1> updater = AtomicIntegerFieldUpdater.newUpdater(AtomicExample1.class, "sum");

    private static AtomicExample1 atomicExample1 = new AtomicExample1();
    public static void main(String[] args) {
        count.compareAndSet(0, 2);
        count.compareAndSet(0, 1);
        count.compareAndSet(1, 3);
        count.compareAndSet(2, 4);
        count.compareAndSet(3, 5);
        log.info("count=>{}", count.get());

        if (updater.compareAndSet(atomicExample1, 100, 120)) {
            log.info("update1 success=>{}", atomicExample1.getSum());
        }

        if (updater.compareAndSet(atomicExample1, 100, 120)) {
            log.info("update2 success=>{}", atomicExample1.getSum());
        } else {
            log.info("update failed=>{}", atomicExample1.getSum());
        }

    }
}

4、AtomicStampReference: CAS 的ABA問題

package com.current.flame.test;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * @author haoxiansheng
 */
@Slf4j
public class AtomicExample2 {
    private static AtomicBoolean isHappend = new AtomicBoolean(false);

    // 請求總數
    public static int clientTotal = 5000;

    // 允許同時執行的線程併發數
    public static int threadTotal = 200;

    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newCachedThreadPool();

        final Semaphore semaphore = new Semaphore(threadTotal); // 信號量 允許有多少個同時執行
        final CountDownLatch countDownLatch = new CountDownLatch(clientTotal); // 閉鎖
        for (int i = 0; i < clientTotal; i++) {
            executorService.execute(()->{
                try {
                    semaphore.acquire();
                    test();
                    semaphore.release();
                } catch (Exception e) {
                    log.info("e=>{}", e.getMessage());
                }
                countDownLatch.countDown();
            });
        }
        countDownLatch.await();
        log.info("isHappend==>{}", isHappend.get());
        executorService.shutdown();
    }

    private  static void test() {

        if (isHappend.compareAndSet(false, true)) {
            log.info("execute");
        }
    }
}

二、原子性、鎖

1、synchroized: 依賴JVM

2、Lock: 依賴特殊的CPU 指令,代碼實現,ReentrantLock。

三、原子性、對比

1、synchroized:不可中斷、適合競爭不激烈,可讀性好

2、Lock: 可中斷鎖、多樣化同步、競爭激烈時能維持常態

3、Atomic:競爭激烈時能維持常態,比Lock性能好;只能同步一個值。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章