亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

java8中CAS的增強

2019-11-15 00:18:14
字體:
來源:轉載
供稿:網友
java8中CAS的增強

注:ifeve.com的同名文章為本人所發,此文在其基礎做了些調整。轉載請注明出處!


一、java8中CAS的增強

前些天,我偶然地將之前寫的用來測試AtomicInteger和synchronized的自增性能的代碼跑了一下,意外地發現AtomicInteger的性能比synchronized更好了,經過一番原因查找,有了如下發現:

在jdk1.7中,AtomicInteger的getAndIncrement是這樣的:

public final int getAndIncrement() {    for (;;) {        int current = get();        int next = current + 1;        if (compareAndSet(current, next))            return current;    }}public final boolean compareAndSet(int expect, int update) {    return unsafe.compareAndSwapInt(this, valueOffset, expect, update);}

而在jdk1.8中,是這樣的:

public final int getAndIncrement() {    return unsafe.getAndAddInt(this, valueOffset, 1);}

可以看出,在jdk1.8中,直接使用了Unsafe的getAndAddInt方法,而在jdk1.7的Unsafe中,沒有此方法?;究梢詳喽ǎ琔nsafe新增的方法是性能提升的關鍵。(文章末尾將附上一些探索的過程及推論)

通過查看AtomicInteger的源碼可以發現,受影響的還有getAndAdd、addAndGet等大部分方法。

結論:有了這次對CAS的增強,我們又多了一個使用非阻塞算法的理由。


二、測試方法

以下給出測試代碼,供參考與測試。需要注意的是,此測試方法簡單粗暴,compareAndSet的性能不如synchronized,并不能簡單地說synchronized就更好,兩者的使用方式是存在差異的,而且在實際使用中,還有業務處理,不可能有如此高的競爭強度,此對比僅作為一個參考,該測試能夠證明的是,AtomicInteger.getAndIncrement的性能有了大幅提升。

package performance;import java.util.concurrent.CountDownLatch;import java.util.concurrent.atomic.AtomicInteger;import java.util.concurrent.locks.LockSupport;/**  * @author trytocatch@163.com  */public class AtomicTest {    //測試規模,調用一次getAndIncreaseX視作提供一次業務服務,記錄提供TEST_SIZE次服務的耗時    PRivate static final int TEST_SIZE = 100000000;    //客戶線程數    private static final int THREAD_COUNT = 10;    //使用CountDownLatch讓各線程同時開始    private CountDownLatch cdl = new CountDownLatch(THREAD_COUNT + 1);    private int n = 0;    private AtomicInteger ai = new AtomicInteger(0);    private long startTime;    public void init() {        startTime = System.nanoTime();    }    /**     * 使用AtomicInteger.getAndIncrement,測試結果為1.8比1.7有明顯性能提升     * @return     */    private final int getAndIncreaseA() {        int result = ai.getAndIncrement();        if (result == TEST_SIZE) {            System.out.println(System.nanoTime() - startTime);            System.exit(0);        }        return result;    }    /**     * 使用synchronized來完成同步,測試結果為1.7和1.8幾乎無性能差別     * @return     */    private final int getAndIncreaseB() {        int result;        synchronized (this) {            result = n++;        }        if (result == TEST_SIZE) {            System.out.println(System.nanoTime() - startTime);            System.exit(0);        }        return result;    }    /**     * 使用AtomicInteger.compareAndSet在java代碼層面做失敗重試(與1.7的AtomicInteger.getAndIncrement的實現類似),     * 測試結果為1.7和1.8幾乎無性能差別     * @return     */    private final int getAndIncreaseC() {        int result;        do {            result = ai.get();        } while (!ai.compareAndSet(result, result + 1));        if (result == TEST_SIZE) {            System.out.println(System.nanoTime() - startTime);            System.exit(0);        }        return result;    }    public class MyTask implements Runnable {        @Override        public void run() {            cdl.countDown();            try {                cdl.await();            } catch (InterruptedException e) {                e.printStackTrace();            }            while (true)                getAndIncreaseA();// getAndIncreaseB();        }    }    public static void main(String[] args) throws InterruptedException {        AtomicTest at = new AtomicTest();        for (int n = 0; n < THREAD_COUNT; n++)            new Thread(at.new MyTask()).start();        System.out.println("start");        at.init();        at.cdl.countDown();    }}

以下是在Intel(R) Core(TM) i7-4710HQ CPU @2.50GHz(四核八線程)下的測試結果(波動較小,所以每項只測試了四五次,取其中一個較中間的值):

jdk1.7AtomicInteger.getAndIncrement 12,653,757,034synchronized 4,146,813,462AtomicInteger.compareAndSet 12,952,821,234jdk1.8AtomicInteger.getAndIncrement 2,159,486,620synchronized 4,067,309,911AtomicInteger.compareAndSet 12,893,188,541

三、提升原因的探索及推論

一開始,我懷疑在1.8中,Unsafe直接使用了native方法,而1.7是在getAndIncrement里完成的失敗重試,也就是在java代碼層面,所以造成了性能的差別,于是我用jad反編譯了Unsafe,得到了如下代碼:

public final int getAndAddInt(Object obj, long l, int i){    int j;    do        j = getIntVolatile(obj, l);    while(!compareAndSwapInt(obj, l, j, j + i));    return j;}public native int getIntVolatile(Object obj, long l);public final native boolean compareAndSwapInt(Object obj, long l, int i, int j);

并且參考了openjdk8的Unsafe源碼:

public final int getAndAddInt(Object o, long offset, int delta) {    int v;    do {        v = getIntVolatile(o, offset);    } while (!compareAndSwapInt(o, offset, v, v + delta));    return v;}public native int     getIntVolatile(Object o, long offset);public final native boolean compareAndSwapInt(Object o, long offset,                                              int expected,                                              int x);

由上面的信息可以看出,1.8中,失敗重試也是在java代碼層面進行的(區別是轉移到了Unsafe的java方法里面),算是推翻了我的猜測,于是我決定通過反射,直接獲取到Unsafe實例,編寫跟Unsafe.getAndAddInt方法一樣的代碼來測試,看能否找到一些新的線索:

...import sun.misc.Unsafe;public class AtomicTest {    ....    private Unsafe unsafe;    private long valueOffset;    public AtomicTest(){        Field f;        try {            f = Unsafe.class.getDeclaredField("theUnsafe");            f.setaccessible(true);            unsafe = (Unsafe)f.get(null);            valueOffset = unsafe.objectFieldOffset(AtomicInteger.class.getDeclaredField("value"));        }catch(NoSuchFieldException e){        ...        }    }    private final int getAndIncreaseD(){        int result;        do{            result = unsafe.getIntVolatile(ai, valueOffset);        }while(!unsafe.compareAndSwapInt(ai, valueOffset, result, result+1));        if(result == MAX){            System.out.println(System.nanoTime()-startTime);            System.exit(0);        }        return result;    }    ...}

但讓人失望的是,該方式跟1.7的getAndIncrement效率一樣,明明跟1.8的Unsafe.getAndAddInt方法一樣,卻是截然不同的效率。

最后,經過ifeve.com的網友們的指點,對性能的提升原因有了如下推論,雖不敢說百分之百正確(因為沒有用jvm的源碼作為論據),但還是有很大把握的,感謝網友@周 可人和@liuxinglanyue!

Unsafe是經過特殊處理的,不能理解成常規的java代碼,區別在于:

  • 1.8在調用getAndAddInt的時候,如果系統底層支持fetch-and-add,那么它執行的就是native方法,使用的是fetch-and-add;
  • 如果不支持,就按照上面的所看到的getAndAddInt方法體那樣,以java代碼的方式去執行,使用的是compare-and-swap;

這也正好跟openjdk8中Unsafe::getAndAddInt上方的注釋相吻合:

  • // The following contain CAS-based Java implementations used on// platforms not supporting native instructions

相關鏈接:http://ashkrit.blogspot.com/2014/02/atomicinteger-java-7-vs-java-8.htmlhttp://hg.openjdk.java.net/jdk8u/hs-dev/jdk/file/a006fa0a9e8f/src/share/classes/sun/misc/Unsafe.java


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品大陆在线观看| 亚洲欧美国产精品久久久久久久| 国产激情视频一区| 国产精品盗摄久久久| 中文字幕亚洲自拍| 国语自产精品视频在线看抢先版图片| 国产aⅴ夜夜欢一区二区三区| 日韩h在线观看| 欧美性猛交xxxx乱大交蜜桃| 国产精品视频精品| 日韩中文字幕视频在线| 91在线观看欧美日韩| 亚洲综合国产精品| 国产视频精品va久久久久久| 日韩精品日韩在线观看| 57pao国产精品一区| 亚洲一区美女视频在线观看免费| 欧美电影第一页| 国模吧一区二区| 久久久最新网址| 美女啪啪无遮挡免费久久网站| 91在线观看免费| 日韩高清电影免费观看完整| 欧美激情视频播放| 亚洲日韩欧美视频| 久久成人18免费网站| 精品高清美女精品国产区| 成人观看高清在线观看免费| 精品视频在线观看日韩| 日韩国产激情在线| 国产午夜精品视频| 日韩美女视频免费在线观看| 国产精品国语对白| 国产精品成人免费视频| 日韩在线中文字幕| 国产午夜精品视频免费不卡69堂| www.国产一区| 午夜精品久久久久久久99热浪潮| 国产亚洲精品激情久久| 欧美成人精品激情在线观看| 成人美女av在线直播| 欧美精品日韩三级| 国外成人在线直播| 国产91在线播放| 日日摸夜夜添一区| 91视频8mav| 国产suv精品一区二区| 国产日韩欧美黄色| 91伊人影院在线播放| zzjj国产精品一区二区| 欧美日韩国产一区中文午夜| 国产精品人人做人人爽| 色偷偷av亚洲男人的天堂| 91大神在线播放精品| 国产欧美 在线欧美| 亚洲电影免费观看高清| 热门国产精品亚洲第一区在线| 一区二区三区在线播放欧美| 国产剧情久久久久久| 欧美性感美女h网站在线观看免费| 九九视频直播综合网| 亚洲在线视频福利| 日本久久91av| 中文欧美在线视频| 色妞久久福利网| 亚洲а∨天堂久久精品9966| 国产亚洲欧美一区| 亚洲精品久久久久久下一站| 91精品视频免费观看| 欧美猛交ⅹxxx乱大交视频| 欧美精品免费在线观看| 日本最新高清不卡中文字幕| 91夜夜未满十八勿入爽爽影院| 久久久久久亚洲| 91丝袜美腿美女视频网站| 狠狠色狠狠色综合日日小说| 欧美日韩色婷婷| 性欧美长视频免费观看不卡| 成人免费福利在线| 亚洲国产精品福利| 欧美日韩国产精品| 国产精品激情av电影在线观看| 亚洲午夜性刺激影院| 欧美丰满少妇xxxx| 清纯唯美日韩制服另类| 亚洲在线观看视频| 中文字幕亚洲无线码在线一区| 狠狠躁夜夜躁人人躁婷婷91| 亚洲免费av片| 日韩a**站在线观看| 国产精品久久久久9999| 亚洲人成在线免费观看| 久久久久久国产精品三级玉女聊斋| 一二美女精品欧洲| 国产精品久久久久久亚洲调教| 97超视频免费观看| 91精品免费看| 中文字幕亚洲一区二区三区| 国产精品一区专区欧美日韩| 日韩视频精品在线| 日韩美女激情视频| 日韩性生活视频| 欧美性生活大片免费观看网址| 日韩黄色高清视频| 精品国产福利在线| 国产成人在线亚洲欧美| 久久影视三级福利片| 久久综合久中文字幕青草| 欧美久久久精品| 欧美有码在线观看| 日本免费一区二区三区视频观看| 波霸ol色综合久久| 中国日韩欧美久久久久久久久| 国产精品久久久久久久久久久久久| 久久久91精品| 欧美在线中文字幕| 国产精品第2页| 亚洲国产欧美一区二区丝袜黑人| 日韩激情片免费| 在线观看久久av| 日韩福利视频在线观看| 国产激情久久久久| 日韩亚洲成人av在线| 国产精品入口福利| 亚洲午夜未删减在线观看| 精品福利一区二区| 亚洲男人天堂2023| 亚洲精品欧美一区二区三区| 国产日韩欧美视频在线| 久久激情视频久久| 中文字幕亚洲一区| 午夜精品福利电影| 久久久国产精彩视频美女艺术照福利| 成人免费视频网址| 97精品久久久中文字幕免费| 草民午夜欧美限制a级福利片| 久久久亚洲影院| 国产精品黄色av| 久久国产精品首页| 97国产精品人人爽人人做| 欧美电影第一页| 欧美黑人性视频| 在线观看亚洲视频| 久久精品夜夜夜夜夜久久| …久久精品99久久香蕉国产| 久久精品亚洲热| 日韩不卡在线观看| 久久久久久亚洲精品| 国产精品激情av在线播放| 亚洲自拍偷拍一区| 高清欧美性猛交| 欧美日韩国产二区| 91色视频在线观看| 欧美老女人在线视频| 97国产suv精品一区二区62| 亚洲精品视频网上网址在线观看| 国产丝袜高跟一区| 狠狠色噜噜狠狠狠狠97| 欧美激情按摩在线| 亚洲a级在线观看| 国产亚洲精品久久久久久777| 狠狠干狠狠久久| 久久久久久亚洲精品不卡| 亚洲国产成人av在线|