Java多線程初級匯總

多線程概述

  • 搶占式多任務

    直接中斷而不需要事先和被中斷程序協商

  • 協作多任務

    被中斷程序同意交出控制權之后才能執行中斷

  • 多線程和多進程區別?

    本質的區別在于每個進程有它自己的變量的完備集,線程則共享相同的數據

Thread

  • Thread(Runnable target)

    構造有一個新的線程來調用指定的target的run()方法

  • void start()

    啟動這個線程,將引發調用run()方法

  • void run()

    調用關聯Runnable的run方法

  • Thread 示例測試代碼

public class ThreadTest extends Thread {

    private Thread mThread;

    private String mName;

    private final int mCount = 4;

    public ThreadTest(String name){
        this.mName = name;
        System.out.println("new ThreadTest"+name);
    }

    public void run(){
        System.out.println("run " + this.mName);
        try {
            for (int i = 0; i < mCount; i++) {
                System.out.println(this.mName + "Thread.sleep : " + i);
                Thread.sleep(50);
            }
        } catch (InterruptedException ie) {
            System.out.println("InterruptedException " + this.mName);
        }
    }

    public void start() {
        System.out.println("start " + this.mName);
        if (this.mThread == null) {
            this.mThread = new Thread(this);
            this.mThread.start();
        }
    }

    public static void main(String[] args) {
        ThreadTest thread1 = new ThreadTest("test1");
        thread1.start();
        ThreadTest thread2 = new ThreadTest("test2");
        thread2.start();
    }
}

Runnable

  • Runnable封裝一個異步運行的任務

  • Runnable示例測試代碼


/**
 * Runnable繼承類
 */
public class RunnableTest implements Runnable {

    private Thread mThread;

    private String mName;

    private final int mCount = 4;

    public RunnableTest(String name) {
        this.mName = name;
        System.out.println("new RunnableTest" + name);
    }

    public void run() {
        System.out.println("run " + this.mName);
        try {
            for (int i = 0; i < mCount; i++) {
                System.out.println(this.mName + "Thread.sleep : " + i);
                Thread.sleep(50);
            }
        } catch (InterruptedException ie) {
            System.out.println("InterruptedException " + this.mName);
        }
    }

    public void start() {
        System.out.println("start " + this.mName);
        if (this.mThread == null) {
            this.mThread = new Thread(this);
            this.mThread.start();
        }
    }

    public static void main(String[] args) {
        RunnableTest run1 = new RunnableTest("test1");
        run1.start();
        RunnableTest run2 = new RunnableTest("test2");
        run2.start();
    }

}


Callable和Future

  • Callable接口是一個參數化的類型,有一個方法call

  • Future保存異步計算的結果。當使用Future對象,啟動有一個計算,把計算結果給某線程,Future對象在所有者結果計算好之后就可以得到它

  • call()

    運行一個將產生結果的任務

  • 代碼示例

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class CallableTest implements Callable<Integer> {

    public Integer call() throws Exception {
        int i = 0;
        for (; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + " " + i);
        }
        return i;
    }

    public static void main(String[] args) {
        CallableTest test = new CallableTest();

        FutureTask<Integer> task = new FutureTask<Integer>(test);

        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + " 的循環變量i的值" + i);
            if (i == 20) {
                new Thread(task, "有返回值的線程").start();
            }
        }

        try {
            System.out.println("子線程的返回值:" + task.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

    }
}

線程池

如果你的程序創建了大量生存期很短的線程,就應該使用線程池一個線程池包含大量準備運行的空閑線程。將一個Runnable對象給線程池,線程池中的一個線程就會調用run方法。
  • newCachedThreadPool 構建,如果有空閑線程可用,立即讓它執行任務,否則創建一個新線程
  • newFixedThreadPool 創建一個大小固定的線程池。如果提交的任務數大于空閑線程數,那么得不到服務的任務將被置于隊列中
  • newSingleTreadExecutor是一個退化了大小為1的線程池
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,825評論 6 546
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,814評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,980評論 0 384
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 64,064評論 1 319
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,779評論 6 414
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,109評論 1 330
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,099評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,287評論 0 291
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,799評論 1 338
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,515評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,750評論 1 375
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,221評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,933評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,327評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,667評論 1 296
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,492評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,703評論 2 380

推薦閱讀更多精彩內容

  • 進程和線程 進程 所有運行中的任務通常對應一個進程,當一個程序進入內存運行時,即變成一個進程.進程是處于運行過程中...
    小徐andorid閱讀 2,830評論 3 53
  • ??一個任務通常就是一個程序,每個運行中的程序就是一個進程。當一個程序運行時,內部可能包含了多個順序執行流,每個順...
    OmaiMoon閱讀 1,699評論 0 12
  • 你我的周圍可能經常有這樣的人,你在和朋友談論某本書或某部電影,他們會湊過來大聲說:“我看過這個,我看了好幾遍...
    蘇吳閱讀 360評論 0 0
  • 他又何嘗聽不出來你言語之中的情誼,他只是裝作不明白而已。如果一個男生真的喜歡一個女生,他一定會表白的
    筆墨紙硯閱讀 202評論 0 0
  • 我仍記得多年前,那個穿著簡單干凈衣服,滿眼澄澈單純的馬尾姑娘。她總是挺直身子高昂著頭,不止一次用勢在必行的語氣告訴...
    騎驢找馬lj閱讀 94評論 0 0