一掰烟、多線程基礎

多線程基礎

基本概念

同步弥虐、異步

  • 同步 線程B要等待線程A的執(zhí)行結果之后才能執(zhí)行。要順序執(zhí)行
image
  • 異步 相對同步來說媚赖,彼此獨立霜瘪,在在等待某事件的過程中可以繼續(xù)做自己的事。
image

這個更直觀 小人相當于一個線程

image

并行/并發(fā)

并發(fā)和并行是異步的兩種實現(xiàn)形式惧磺,并行是真正的異步

  • 并發(fā)

    • 單核cpu情況颖对,同一時刻只能分配給一個線程使用。其他等待磨隘。是邏輯層面的同時工作
    image
  • 并行

    • 多核cpu情況下缤底,每個cpu都可以分配一個線程使用,同一時刻執(zhí)行多個并發(fā)任務番捂。叫并行


      image

線程狀態(tài)

image

線程狀態(tài)共5種:創(chuàng)建个唧、就緒、運行设预、==阻塞(阻塞徙歼、等待、鎖定)==、終止魄梯。

創(chuàng)建線程

  • 繼承Thread類

public class A extends Thread {
    //繼承Thread類 實現(xiàn)run接口
    @Override
    public void run() {
        System.out.println("123");
    }

    public static void main(String[] args) {
        A a = new A();//創(chuàng)建線程桨螺,線程進入創(chuàng)建狀態(tài)
        a.start();//開啟線程,線程進入runnable
    }
}

  • 實現(xiàn)Runable接口
public class A implements Runnable {
    //繼承Thread類 實現(xiàn)run接口
    @Override
    public void run() {
        System.out.println("123");
    }

    public static void main(String[] args) {
        //創(chuàng)建一個runable實現(xiàn)類的對象
        A a = new A();
        //不是啟動線程酿秸,只是方法調用
       a.run();
    }
}
  • 實現(xiàn)Callable接口
public class A implements Callable<Integer> {
    //繼承Callable類 實現(xiàn)call接口 call具有返回值
    @Override
    public Integer call() throws Exception {
        return 123;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //創(chuàng)建一個callable實現(xiàn)類的對象
        A a = new A();
        //用FutureTask封裝
        FutureTask<Integer> future = new FutureTask<Integer>(a);
        //創(chuàng)建一個線程
        Thread thread = new Thread(future);
        thread.start();
        //線程啟動后可以獲取返回值
        Integer integer = future.get();
        System.out.println(integer);
    }
}

實現(xiàn)Runnable接口比繼承Thread類優(yōu)勢:

  • 線程池只能放入實現(xiàn)Runable的

  • 避免單繼承的限制

  • 代碼被多個線程共享灭翔,代碼和數(shù)據(jù)獨立,例如

    • 繼承Thread
int ticket=10;

MyThread t1=new MyThread();
t1.start();
MyThread t2=new MyThread();
t2.start();
//上面的代碼  就會賣出20張票 沒有數(shù)據(jù)共享
    • 實現(xiàn)接口
int ticket=10;

MyThread t=new MyThread();
t.run();
t.run(); 
//這樣多個線程的時候辣苏,就能實現(xiàn)數(shù)據(jù)共享

線程其他狀態(tài)

  • Runnable(就緒)

    線程調用start()方法肝箱,狀態(tài)為可執(zhí)行,等待獲取cpu的使用權

  • Running(運行狀態(tài))

    獲得cpu的使用權稀蟋,執(zhí)行代碼狭园。

  • Blocked(阻塞)

    • 等待阻塞

      執(zhí)行wait()方法,jvm把該線程放入==等待池==

    • 同步阻塞

      獲取同步鎖時糊治,鎖被其他線程占用唱矛,jvm把該線程放入==鎖池==

    • 其他阻塞

      執(zhí)行sleep()或join()或發(fā)出i/o請求時,jvm把線程設置為阻塞狀態(tài)

常用函數(shù)說明

  1. sleep()

    • 在指定的毫秒數(shù)內讓線程休眠井辜,進入阻塞狀態(tài)绎谦。
  2. join()

    • 主線程需要等待調用join的子線程執(zhí)行完畢。
  3. yield() 退讓

    • 暫停當前正在執(zhí)行的線程對象粥脚,并執(zhí)行其他線程窃肠,該線程進入runnable狀態(tài)
    • 目的:是為了讓相同優(yōu)先級的線程之間輪轉執(zhí)行。
    • 實際情況下刷允,并不一定有效果冤留,因為讓步之后,該線程還是有可能被再次選中
sleep yield
在指定時間內肯定不會被執(zhí)行 隨時都可以獲取鎖
允許較低優(yōu)先級的線程獲得運行機會 只能同級
  1. interrupt() 中斷
    • 并不能中斷線程树灶!
    • 只是給線程發(fā)出一個中斷信號纤怒。
  2. wait()休眠
    • 線程在獲取對象鎖之后,釋放對象鎖天通,所以必須是再synchronized{}中
  3. notify() 喚醒
    • 線程對對象鎖的喚醒操作泊窘。也要和synchronized{}搭配使用
    • notify并不能馬上獲取對象鎖,而是再synchronized語句塊結束像寒,自動釋放鎖之后烘豹,jvm在所有的wait()的線程中隨機選取。
  • 有個經典的題诺祸,就是三個線程携悯。分別打印10次A、B筷笨、C,要求順序執(zhí)行

多種實現(xiàn)

思路如圖
image
public class MyThreadPrinter implements Runnable {
    private String name;
    private Object prev;
    private Object self;

    /**
     *
     * @param name   需要打印的東西
     * @param prev   上一個對象
     * @param self   自己
     */
    private MyThreadPrinter(String name, Object prev, Object self) {
        this.name = name;
        this.prev = prev;
        this.self = self;
    }

    @Override
    public void run() {
        int count = 10;
        while (count > 0) {
            //需要獲取上一個對象的鎖和本身的鎖
            synchronized (prev) {
                synchronized (self) {
//重點在這
                    //打印本身的信息
                    System.out.print(name);
                    count--;
                    // 打印完 name了 可以喚醒了  因為上一個線程把本身給wait了
                    self.notify();
                }
                try {
                   // 釋放鎖 等待notify才可以重新獲取鎖
                    //比如a執(zhí)行完 需要執(zhí)行b 需要 b a鎖 就把c給wait
                    prev.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }
    }

    public static void main(String[] args) throws Exception {
        Object a = new Object();
        Object b = new Object();
        Object c = new Object();

        MyThreadPrinter pa = new MyThreadPrinter("A", c, a);
        //pa執(zhí)行完 c就wait了 只有a b可以獲取鎖
        MyThreadPrinter pb = new MyThreadPrinter("B", a, b);
        MyThreadPrinter pc = new MyThreadPrinter("C", b, c);

        new Thread(pa).start();
        Thread.sleep(100);  //確保按順序A憔鬼、B龟劲、C執(zhí)行
        new Thread(pb).start();
        Thread.sleep(100);
        new Thread(pc).start();
        Thread.sleep(100);
    }

}
  • wait / sleep
wait sleep
釋放鎖 沒有釋放鎖
只能在同步快sync中使用 任何地方
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市逊彭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌构订,老刑警劉巖侮叮,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異悼瘾,居然都是意外死亡囊榜,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進店門亥宿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來卸勺,“玉大人,你說我怎么就攤上這事烫扼∈锴螅” “怎么了?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵映企,是天一觀的道長悟狱。 經常有香客問我,道長堰氓,這世上最難降的妖魔是什么挤渐? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮双絮,結果婚禮上浴麻,老公的妹妹穿的比我還像新娘。我一直安慰自己囤攀,他們只是感情好软免,可當我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著焚挠,像睡著了一般或杠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上宣蔚,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天向抢,我揣著相機與錄音,去河邊找鬼胚委。 笑死挟鸠,一個胖子當著我的面吹牛,可吹牛的內容都是我干的亩冬。 我是一名探鬼主播艘希,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼硼身,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了覆享?” 一聲冷哼從身側響起佳遂,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎撒顿,沒想到半個月后丑罪,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡凤壁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年吩屹,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拧抖。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡煤搜,死狀恐怖,靈堂內的尸體忽然破棺而出唧席,到底是詐尸還是另有隱情擦盾,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布淌哟,位于F島的核電站厌衙,受9級特大地震影響,放射性物質發(fā)生泄漏绞绒。R本人自食惡果不足惜婶希,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蓬衡。 院中可真熱鬧喻杈,春花似錦、人聲如沸狰晚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽壁晒。三九已至瓷们,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間秒咐,已是汗流浹背谬晕。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留携取,地道東北人攒钳。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像雷滋,于是被迫代替她去往敵國和親不撑。 傳聞我的和親對象是個殘疾皇子文兢,可洞房花燭夜當晚...
    茶點故事閱讀 45,512評論 2 359

推薦閱讀更多精彩內容