002--volatile 關(guān)鍵字-內(nèi)存可見性

話題一:多線程的3種創(chuàng)建方式

Java使用Thread類代表線程,所有的線程對象都必須是Thread類或其子類的實例。Java可以用三種方式來創(chuàng)建線程,如下所示:
1)繼承Thread類創(chuàng)建線程
2)實現(xiàn)Runnable接口創(chuàng)建線程
3)使用Callable和Future創(chuàng)建線程


話題二:wait和notify的理解與使用

  • 案例分析wait和notify

  • wait和notify知識補充:首先要理解notify()和wait(),因為這兩個方法本來就不屬于Thread類,而是屬于最底層的object基礎(chǔ)類的,也就是說不光是Thread,每個對象都有notify和wait的功能,為什么

因為他們是用來操縱鎖的,而每個對象都有鎖,鎖是每個對象的基礎(chǔ),既然鎖是基礎(chǔ)的,那么操縱鎖的方法當(dāng)然也是最基礎(chǔ)了.


話題三:同樣是線程休眠:wait(),sleep(),suspend()有什么區(qū)別呢?

  • wait:讓當(dāng)前線程阻塞,同時又“積極”地等待條件發(fā)生改變,這一點很關(guān)鍵,sleep和suspend無法做到.
    1)因為我們有時候需要通過同步(synchronized)的幫助來防止線程之間的沖突,而一旦使用同步,就要鎖定對象,也就是獲取對象鎖,其它要使用該對象鎖的線程都只能排隊等著,等到同步方法或者同步塊里的程序全部運行完才有機會.在同步方法和同步塊中,無論sleep()還是suspend()都不可能自己被調(diào)用的時候解除鎖定,他們都霸占著正在使用的對象鎖不放

    2) 而wait卻可以,它可以讓同步方法或者同步塊暫時放棄對象鎖,而將它暫時讓給其它需要對象鎖的人(這里應(yīng)該是程序塊,或線程)用,這意味著可在執(zhí)行wait()期間調(diào)用線程對象中的其他同步方法!在其它情況下(sleep啊,suspend啊),這是不可能的.

    3) 但是注意我前面說的,只是暫時放棄對象鎖,暫時給其它線程使用,我wait所在的線程還是要把這個對象鎖收回來的!

  • sleep:

  • suspend:


話題四:wait()暫時放棄對象鎖后,如何將對象鎖收回來?

  • 第一種方法,限定借出去的時間.在wait()中設(shè)置參數(shù),比如wait(1000),以毫秒為單位,就表明我只借出去1秒中,一秒鐘之后,我自動收回:wait(long timeout);
  • 第二種方法,讓借出去的人通知我,他用完了,要還給我了.這時,我馬上就收回來:notify();
  • PS:.哎,假如我設(shè)了1小時之后收回,別人只用了半小時就完了,那怎么辦呢?靠!當(dāng)然用完了就收回了,還管我設(shè)的是多長時間啊!

話題五:線程的可用方法展示

  • notify():通知
  • wait():等待
  • run():執(zhí)行
查看Thread線程的方法

話題六:synchronized和volatile?

1.volatile問題引出

// 老師演示的時候,有一個問題,雖然子線程falg=true,但是main線程打印依然是false!但是在我的JDK上沒有重現(xiàn)這一個現(xiàn)象
public class TestVolatile {
    public static void main(String[] args) throws Exception {
        // 1.創(chuàng)建一個線程
        MyThreadA myThreadA = new MyThreadA();
        new Thread(myThreadA).start();
        new Thread(myThreadA).start();
        
        // 2.mian主線程
        while(true){
            if (myThreadA.flag) {
                System.out.println("-------------主線程flag:"+myThreadA.flag);
                Thread.sleep(1000);
            }else{
                System.out.println("*************主線程flag:"+myThreadA.flag);
                Thread.sleep(1000);
            }
        }
    }
}
class MyThreadA implements Runnable{
    public boolean flag = Boolean.FALSE;
    
    @Override
    public void run() {
        try {
            System.out.println("-----------自定義線程執(zhí)行休眠1s");
            Thread.sleep(200);
            flag = Boolean.TRUE;
            System.out.println("-----------休眠結(jié)束flag:"+flag);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

2.synchronized(object){}代表什么含義?
- 只能由一個線程同時使用object
- 多線程時,先判斷鎖,有鎖就要將后續(xù)線程阻塞掛起,直到下一次CPU重新給他進(jìn)行任務(wù)分配
- 加鎖的這種效率是最低的!但是又需要刷新數(shù)據(jù)(內(nèi)存可見性的問題),怎么辦?--volatile
- volatile可以保證多個線程在訪問相同數(shù)據(jù)時候,數(shù)據(jù)是實時可見的(實時將緩存數(shù)據(jù)刷新到主存中)!


3.synchronized和volatile比較
- volatile對比于synchronized,是一種輕量級的同步策略!
- volatile不具備"互斥性",不能保證只有一個線程使用共享數(shù)據(jù)
- volatile不能保證變量的原子性


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 本文出自 Eddy Wiki ,轉(zhuǎn)載請注明出處:http://eddy.wiki/interview-java.h...
    eddy_wiki閱讀 2,215評論 0 14
  • Java多線程學(xué)習(xí) [-] 一擴展javalangThread類 二實現(xiàn)javalangRunnable接口 三T...
    影馳閱讀 2,981評論 1 18
  • 本文主要講了java中多線程的使用方法、線程同步、線程數(shù)據(jù)傳遞、線程狀態(tài)及相應(yīng)的一些線程函數(shù)用法、概述等。 首先講...
    李欣陽閱讀 2,482評論 1 15
  • 結(jié)局或開始——獻(xiàn)給遇羅克作者:北島 我,站在這里代替另一個被殺害的人為了每當(dāng)太陽升起讓沉重的影子象道路穿過整個國土...
    a9427bd9da65閱讀 1,778評論 2 4
  • 《太陽的后裔》里,收到柳大尉的遺書,姜暮煙哭紅了眼;而尹明珠一直帶在身邊,卻沒有打開過。一瞬間,腦子里有一個想法,...
    甪璽閱讀 2,174評論 0 2