日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Java并發(fā)多線程編程——Volatile原理與使用

 鷹兔牛熊眼 2021-04-22

優(yōu)質(zhì)文章,第一時間送達

76套java從入門到精通實戰(zhàn)課程分享

一、volitile的理解

  • Volatile稱之為輕量級鎖,被volatile修飾的變量,在線程之間是可見的。

  • 可見即一個線程修改了這個變量的值,在另外一個線程中能夠讀到這個修改后的值。

  • Synchronized除了線程之間互斥以外,還有一個非常大的作用就是保證可見性。

  • 保證可見性的前提,多個線程拿到的是同一把鎖,否則是保證不了的。

二、多個線程獲取值案例(沒有使用同步的情況)

1、代碼

package com.xz.thread.t6;

/**
 * @description: 保證可見性的前提:多個線程拿到的是同一把鎖,否則是保證不了的。
 *
 * @author: xz
 */
public class Demo {
    private int a=1;

    public int getA() {
        return a;
    }

    public void setA(int a) {
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.a = a;
    }

    public static void main(String[] args) {
        Demo d=new Demo();
        //第一個線程
        new Thread(new Runnable() {
            @Override
            public void run() {
                d.setA(10);
            }
        }).start();
        //第二個線程
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(d.getA());
            }
        }).start();

        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println('最終的結(jié)果:'+d.getA());
    }
}


2、輸出結(jié)果

圖片

3、結(jié)論

  • 在沒有使用同步的情況下,同一個實例中多個線程獲取的值是不相同的。

三、多個線程獲取值案例(使用Volatile關鍵字的情況)

1、代碼

package com.xz.thread.t6;

/**
 * @description: 保證可見性的前提:多個線程拿到的是同一把鎖,否則是保證不了的。
 * @author: xz
 */
public class Demo2 {
    public volatile int a = 1;

    public static void main(String[] args) {

        Demo2 d=new Demo2();
        new Thread(new Runnable() {
            @Override
            public void run() {
                d.a = 10;
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(d.a);
            }
        }).start();

        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println('最終的結(jié)果:'+d.a);
    }
}


2、輸出結(jié)果

圖片

3、結(jié)論

  • 在使用Volatile關鍵字的情況下,同一個實例中多個線程獲取的值是相同的。

四、多個線程獲按順序執(zhí)行的案例

1、代碼

package com.xz.thread.t6;

/**
 * @description:
 * @author: xz
 */
public class Demo3 {

    public volatile Boolean run =false;

    public static void main(String[] args) {
        Demo3 d3=new Demo3();

        //第一個線程
        new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i=0;i<10;i++){
                    System.out.println('第【'+i+'】次執(zhí)行');
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                d3.run =true;//第一個線程執(zhí)行完把run變量改成true
            }
        }).start();

        //第二個線程
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (!d3.run){
                    //當run !=true 時,不執(zhí)行
                }
                System.out.println('線程2執(zhí)行了===========');
            }
        }).start();
    }
}


2、輸出結(jié)果

圖片

五、 Lock指令的理解

  • volatile可見性是通過匯編加上Lock前綴指令完成的。由此引出Lock指令的理解。

  • 在多處理器的系統(tǒng)上

  • 將當前處理器緩存行的內(nèi)容寫回到系統(tǒng)內(nèi)存;

  • 這個寫回到內(nèi)存的操作會使在其他CPU里緩存了該內(nèi)存地址的數(shù)據(jù)失效。

六、有Volatile為什么還使用synchronized

  • volatile關鍵字可以保證內(nèi)存可見性和有序性,但不能保證原子性;

  • 也就是說synchronized可以取代Volatile,但是Volatile不能取代synchronized;

七、synchronized可以取代Volatile,為什么還用Volatile

  • Volatile稱之為輕量級鎖。

————————————————

版權聲明:本文為CSDN博主「小志的博客」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多