Java併發編程-原子操做的實現原理

原子(atomic)本意時「不能被進一步分割的最小粒子」,而原子操做(atomic operation)意爲「不可被中斷的一個或一系列操做」。java

Java 如何實現原子操做

在 Java 中能夠經過鎖和循環 CAS 的方式實現原子操做。安全

一、使用循環 CAS 實現原子操做多線程

JVM 中的 CAS 操做正是利用了處理器提供的 CMPXCHG 指令實現的。自旋 CAS 實現的基本思路就是循環進行 CAS 操做直到成功爲止,如下代碼實現了一個基於 CAS 線程安全的計數器方法 safeCount 和一個非線程安全的計數器 count。atom

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Author: YiFan
 * Date: 2018/11/25 20:39
 * Description: CAS操做
 */
public class CASTest {

    private AtomicInteger atomicI = new AtomicInteger(0);
    private int i = 0;

    public static void main(String[] args) throws InterruptedException {
        final CASTest cas = new CASTest();
        List<Thread> threads = new ArrayList<>(600);
        long start = System.currentTimeMillis();
        for (int i = 0; i < 100; i++) {
            Thread t = new Thread(() -> {
                for (int j = 0; j < 10000; j++) {
                    cas.count();
                    cas.safeCount();
                }
            });
            threads.add(t);
        }
        for (Thread t:
                threads
             ) {
            t.start();
        }
        // 等待全部線程執行完成
        for (Thread t:
                threads
             ) {
            t.join();
        }
        System.out.println(cas.i);
        System.out.println(cas.atomicI.get());
        System.out.println(System.currentTimeMillis() - start);
    }

    // 非線程安全計數器
    private void count() {
        i++;
    }

    // 使用CAS實現線程安全計數器
    private void safeCount() {
        for (;;) {
            int i = atomicI.get();
            boolean suc = atomicI.compareAndSet(i, ++i);
            if (suc) {
                break;
            }
        }
    }
}

該示例演示了多線程下對共享變量進行操做,count 方法中沒有使用 CAS 操做,致使多個線程能夠同時對共享變量 i 進行操做,因此致使最終的 i 值不爲 100000。可是 safeCount 方法中使用了 CAS 操做,這樣就解決的多線程下對 i++ 的原子性操做了,因此最終 i 值始終爲 100000。線程

二、使用鎖機制實現原子操做code

鎖機制保證了只有得到鎖的線程纔可以操做鎖定的內存區域。JVM 內部實現了不少種鎖機制,有偏向鎖、輕量級鎖和互斥鎖。其中 JVM 實現鎖的方式都用了循環 CAS,即當一個線程想進入同步塊的時候使用循環 CAS 的方式來獲取鎖,當他退出同步塊的時候使用循環 CAS 釋放鎖。ip

相關文章
相關標籤/搜索