国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JAVA并發(fā)編程之-Volatile關(guān)鍵字及內(nèi)存可見性

xcold / 1906人閱讀

摘要:的缺點(diǎn)頻繁刷新主內(nèi)存中變量,可能會造成性能瓶頸不具備操作的原子性,不適合在對該變量的寫操作依賴于變量本身自己。

作者:畢來生
微信:878799579
1. 什么是JUC?

JUC全稱 java.util.concurrent 是在并發(fā)編程中很常用的實(shí)用工具類

2.Volatile關(guān)鍵字

1、如果一個變量被volatile關(guān)鍵字修飾,那么這個變量對所有線程都是可見的。
2、如果某條線程修改了被Volatile修飾的這個變量值,修改后的值對于其他線程來時是立即可見的。
3、并不是經(jīng)過Volatile修飾過的變量在多線程下就是安全的
4、多線程間可以使用SynchronousQueue或者Exchanger進(jìn)行數(shù)據(jù)之間傳遞

3.內(nèi)存可見性

內(nèi)存可見性(Memory Visibility)是指當(dāng)某個線程正在使用對象狀態(tài) 而另一個線程在同時修改該狀態(tài),需要確保當(dāng)一個線程修改了對象 狀態(tài)后,其他線程能夠看到發(fā)生的狀態(tài)變化。
可見性錯誤是指當(dāng)讀操作與寫操作在不同的線程中執(zhí)行時,我們無法確保執(zhí)行讀操作的線程能適時地看到其他線程寫入的值,有時甚至是根本不可能的事情。
原理同CAS原理相同,不懂的同學(xué)可以自行百度,附上一張CAS演示圖供大家參考

4.實(shí)戰(zhàn)舉例

通過線程來修改變量count的值,使用Volatile關(guān)鍵字修飾和不使用Volatile修飾count變量結(jié)果對比。

首先我們來看一下通過內(nèi)部類實(shí)現(xiàn)Runnable,變量使用Volatile關(guān)鍵字修飾演示以及結(jié)果

package org.bilaisheng.juc;

/**
 * @Author: bilaisheng
 * @Wechat: 878799579
 * @Date: 2019/1/1 16:29
 * @Todo: 通過內(nèi)部類實(shí)現(xiàn)Runnable,變量使用Volatile關(guān)鍵字修飾演示
 * @Version : JDK11 , IDEA2018
 */
public class NoVolatileTest{

    public static void main(String[] args) {
        NoVolatileThread noVolatileThread = new NoVolatileThread();
        new Thread(noVolatileThread).start();

        while (true){
            if(noVolatileThread.isFlag()){
                System.out.println("flag 此時為true !");
                break;
            }
        }
    }
}

class NoVolatileThread implements Runnable{

    private boolean flag = false;
    
    @Override
    public void run() {
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        flag = true;

        System.out.println(Thread.currentThread().getName() + " flag = " + flag);
    }

    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }
}

運(yùn)行結(jié)果如下圖所示:

接下來我們來看一下通過內(nèi)部類實(shí)現(xiàn)Runnable,變量不使用Volatile關(guān)鍵字修飾演示以及結(jié)果

package org.bilaisheng.juc;

/**
 * @Author: bilaisheng
 * @Wechat: 878799579
 * @Date: 2019/1/1 16:53
 * @Todo: 通過內(nèi)部類實(shí)現(xiàn)Runnable,變量使用Volatile關(guān)鍵字修飾演示
 * @Version : JDK11 , IDEA2018
 */
public class VolatileTest{

    public static void main(String[] args) {
        VolatileThread volatileThread = new VolatileThread();
        new Thread(volatileThread).start();

        while (true){
            // if的判斷volatile保證當(dāng)時確實(shí)正確,然后線程a可能處于休眠狀態(tài),
            // 線程b也判斷不存在,b線程就new了一個。
            // 然后a線程wake up,據(jù)需執(zhí)行new volatile獲取最新值。
            if(volatileThread.isFlag()){
                System.out.println("flag 此時為true !");
                break;
            }
        }
    }
}

class VolatileThread implements Runnable{

    private volatile boolean flag = false;

    @Override
    public void run() {
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        flag = true;

        System.out.println(Thread.currentThread().getName() + " flag = " + flag);
    }

    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }
}

運(yùn)行結(jié)果如下圖所示:

通過對比我們發(fā)現(xiàn)在通過Volatile修飾和不通過Volatile修飾的變量,輸出結(jié)果竟然會有些偏差。到底是為什么呢?

我們逐步拆解上面代碼執(zhí)行步驟:

1、針對于不使用Volatile關(guān)鍵字修飾變量:

步驟一:默認(rèn)flag = false;

步驟二main線程的緩存區(qū)域沒有刷新 flag的值。所以flag 還是false。故沒有輸出

步驟三:子線程輸出 Thread-0 flag = true

2、針對于使用Volatile關(guān)鍵字修飾變量:

步驟一:默認(rèn)flag = false;

步驟二:主線程看到flag是被Volatile關(guān)鍵字修飾的變量。則獲取最新的flag變量值,此時flag = true。故輸出

步驟三:子線程輸出 Thread-0 flag = true

5. Volatile的優(yōu)點(diǎn)

可見性:被Volatile修飾的變量可以馬上刷新主內(nèi)存中的值,保證其他線程在獲取時可以獲取最新值,所有線程看到該變量的值均相同。

輕量級的synchronized,高并發(fā)下保證變量的可見性。

6.Volatile的缺點(diǎn)

1、頻繁刷新主內(nèi)存中變量,可能會造成性能瓶頸

2、不具備操作的原子性,不適合在對該變量的寫操作依賴于變量本身自己。例如i++,并不能通過volatile來保證原子性

喜歡就關(guān)注我吧

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/75621.html

相關(guān)文章

  • 并發(fā)編程的藝術(shù)

    摘要:假設(shè)不發(fā)生編譯器重排和指令重排,線程修改了的值,但是修改以后,的值可能還沒有寫回到主存中,那么線程得到就是很自然的事了。同理,線程對于的賦值操作也可能沒有及時刷新到主存中。線程的最后操作與線程發(fā)現(xiàn)線程已經(jīng)結(jié)束同步。 很久沒更新文章了,對隔三差五過來刷更新的讀者說聲抱歉。 關(guān)于 Java 并發(fā)也算是寫了好幾篇文章了,本文將介紹一些比較基礎(chǔ)的內(nèi)容,注意,閱讀本文需要一定的并發(fā)基礎(chǔ)。 本文的...

    curlyCheng 評論0 收藏0
  • 來,了解一下Java內(nèi)存模型(JMM)

    摘要:因?yàn)楣芾砣藛T是了解手下的人員以及自己負(fù)責(zé)的事情的。處理器優(yōu)化和指令重排上面提到在在和主存之間增加緩存,在多線程場景下會存在緩存一致性問題。有沒有發(fā)現(xiàn),緩存一致性問題其實(shí)就是可見性問題。 網(wǎng)上有很多關(guān)于Java內(nèi)存模型的文章,在《深入理解Java虛擬機(jī)》和《Java并發(fā)編程的藝術(shù)》等書中也都有關(guān)于這個知識點(diǎn)的介紹。但是,很多人讀完之后還是搞不清楚,甚至有的人說自己更懵了。本文,就來整體的...

    kviccn 評論0 收藏0
  • 來,了解一下Java內(nèi)存模型(JMM)

    摘要:因?yàn)楣芾砣藛T是了解手下的人員以及自己負(fù)責(zé)的事情的。處理器優(yōu)化和指令重排上面提到在在和主存之間增加緩存,在多線程場景下會存在緩存一致性問題。有沒有發(fā)現(xiàn),緩存一致性問題其實(shí)就是可見性問題。 網(wǎng)上有很多關(guān)于Java內(nèi)存模型的文章,在《深入理解Java虛擬機(jī)》和《Java并發(fā)編程的藝術(shù)》等書中也都有關(guān)于這個知識點(diǎn)的介紹。但是,很多人讀完之后還是搞不清楚,甚至有的人說自己更懵了。本文,就來整體的...

    eccozhou 評論0 收藏0
  • Java并發(fā)編程實(shí)戰(zhàn)」對象的共享

    摘要:當(dāng)某個不應(yīng)該發(fā)布的對象被發(fā)布時,這種情況被稱為逸出。線程安全共享線程安全的對象在其內(nèi)部實(shí)現(xiàn)同步,因此多線程可以通過對象的公有接口來進(jìn)行訪問而不需要進(jìn)一步的同步。 前言   本系列博客是對《Java并發(fā)編程實(shí)戰(zhàn)》的一點(diǎn)總結(jié),本篇主要講解以下幾個內(nèi)容,內(nèi)容會比較枯燥??赡艽蠹铱礃?biāo)題不能能直觀的感受出到底什么意思,這就是專業(yè)術(shù)語,哈哈,解釋下,術(shù)語(terminology)是在特定學(xué)科領(lǐng)域用...

    phodal 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<