日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

本篇文章我們以AtomicInteger為例子,主要講解下CAS(Compare And Swap)功能是如何在AtomicInteger中使用的,以及提供CAS功能的Unsafe對象。

我們先從一個例子開始吧。假設現在我們要實現多線程應用中的int值自增(單個應用范圍),應該怎么做呢?

我們可能首先想到的是利用synchronized關鍵字,大概的代碼如下:

private static volatile int value;

public static void main(String[] args) {
        Runnable run = new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 1000; i++) {
                    increaseBySync();
                }
            }
        };
        
        Thread t1 = new Thread(run);
        Thread t2 = new Thread(run);
        t1.start();
        t2.start();
        
        while (Thread.activeCount() > 1) {
            Thread.yield();
        }
        System.out.println(value);
}

private static synchronized int increaseBySync() {
        return value++;
}

上面的例子有兩個線程同時對value變量做自增操作,通過對increaseBySync方法加synchronized鎖實現了線程安全的int值自增。

synchronized性能問題

當多個線程訪問某個syncronized方法或者代碼塊的時候,線程間的切換和其他線程等待的時間間隔(取決于OS實現,存在不確定性),由此帶來的性能損耗是比較大的。從JDK5開始,我們可以借助于
JAVA.util.concurrent.atomic包所提供的一些工具類,來實現上述的功能,AtomicInteger就是其中的一個類,它使用了CPU級別的CAS功能,利用它我們可以寫出更高效的代碼。

private static AtomicInteger atomicInteger = new AtomicInteger(0);
public static void main(String[] args) {
        Runnable run = new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 1000; i++) {
                    atomicInteger.incrementAndGet();
                }
            }
        };
        
        Thread t1 = new Thread(run);
        Thread t2 = new Thread(run);
        t1.start();
        t2.start();
        
        while (Thread.activeCount() > 1) {
            Thread.yield();
        }
        System.out.println(atomicInteger.get());
}

上面的代碼同樣能達到多線程自增的效果,但是更高效。

AtomicInteger源碼分析

下面我們來看下AtomicInteger內部是如何實現的呢。

private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;

static {
  try {
    valueOffset = unsafe.objectFieldOffset
    (AtomicInteger.class.getDeclaredField("value"));
  } catch (Exception ex) { throw new Error(ex); }
}

private volatile int value;

首先它有一個用volatile修飾的int變量value,volatile這里主要是保證對value值的更新對每個線程的可見性,關于volatile的介紹可以參考文章末的鏈接。

這里比較關鍵的是Unsafe類型的對象。通過它的名字JDK開發者想告訴我們它是不安全的,但是它又提供了一些JVM無法提供的功能,例如CAS就是其中一個。

CAS

下面是AtomicInteger類中的一個方法,它通過Unsafe對象調用了CAS功能。CAS是目前幾乎所有CPU都提供的一個功能,而且是原子操作,借助它可以實現很多高效的功能。

public final boolean compareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}

其他atomic工具類


java.util.concurrent.atomic包下面Atomic開頭的類都是基于CAS實現的,大家有興趣可以看看源碼,如果理解了上面所說的,其他的都很類似。

  • AtomicBoolean
  • AtomicIntegerArray
  • AtomicLong
  • AtomicReference
  • 。。。

其他文章

Java并發之volatile關鍵字

Demo代碼位置


src/main/java/net/weichitech/juc/AtomicIntegerTest.java · 小西學編程/java-learning - Gitee.com

分享到:
標簽:JAVA
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定