談?wù)凧ava中線程的執(zhí)行順序

線程執(zhí)行順序

我們先來看一個簡單的例子,我們顯示地創(chuàng)建三個線程t1、t2执虹、t3,按照聲明的順序聪姿,依次分別調(diào)用線程的start方法,線程的執(zhí)行順序是怎樣的乙嘀?程序執(zhí)行的結(jié)果會如何末购?:

public class ThreadOrderDemo {
    // 顯示地創(chuàng)建三個線程,觀察執(zhí)行順序
    static Thread t1 = new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("This is thread1");
        }
    });
    static Thread t2 = new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("This is thread2");
        }
    });
    static Thread t3 = new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("This is thread3");
        }
    });
    public static void main(String[] args) throws Exception {
        t1.start();
        t2.start();
        t3.start();
    }
}

猜測程序執(zhí)行結(jié)果:
1.按照代碼順序執(zhí)行虎谢,依次為t1盟榴、t2、t3:

This is thread1
This is thread2
This is thread3

2.按照CPU調(diào)度規(guī)則婴噩,順序隨機:

This is thread1
This is thread3
This is thread2

我們經(jīng)過編輯器執(zhí)行擎场,會發(fā)現(xiàn)結(jié)果是2,按照CPU調(diào)度几莽,執(zhí)行順序隨機迅办。
那我們?nèi)绾巫尵€程有序執(zhí)行呢?以下有兩種方式章蚣。

方式一:使用join讓主線程等待

public static void main(String[] args) throws Exception {
        // 方式一:使用join讓主線程等待
        t1.start();
        t1.join();

        t2.start();
        t2.join();
        
        t3.start();
    }

上述改寫主線程main方法站欺,使用Thread類提供的join方法,可以達到讓線程有序執(zhí)行的效果纤垂。

public final synchronized void join(long millis)
    throws InterruptedException {
        long base = System.currentTimeMillis();
        long now = 0;

        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (millis == 0) {
            while (isAlive()) {
                wait(0);
            }
        } else {
            while (isAlive()) {
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
    }

查看Thread類源碼矾策,可知,此處join方法峭沦,實質(zhì)上是通過調(diào)用Object的wait方法贾虽,讓主線程等待子線程執(zhí)行,子線程執(zhí)行完之后熙侍,主線程再執(zhí)行榄鉴。

方式二:使用線程池隊列

public class ThreadOrderDemo {
    // 顯示地創(chuàng)建三個線程履磨,觀察執(zhí)行順序
    static Thread t1 = new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("This is thread1");
        }
    });
    static Thread t2 = new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("This is thread2");
        }
    });
    static Thread t3 = new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("This is thread3");
        }
    });
    static ExecutorService executor = Executors.newSingleThreadExecutor();
  
    public static void main(String[] args) throws Exception {
        // 方式二:使用線程池隊列
       executor.submit(t1);
       executor.submit(t2);
       executor.submit(t3);
    }
}

上述使用J.U.C(java.util.concurrent)包中的ExecutorService建立線程池隊列蛉抓,以保持線程有序執(zhí)行。

public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }
public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }

序號 參數(shù)名 類型 含義
1 corePoolSize int 核心線程池大小
2 maximumPoolSize int 最大線程池大小
3 keepAliveTime long 線程最大空閑時間
4 unit TimeUnit 時間單位
5 workQueue BlockingQueue<Runnable> 線程等待隊列
6 threadFactory ThreadFactory 線程創(chuàng)建工廠
7 handler RejectedExecutionHandler 拒絕策略

上述Executors.newSingleThreadExecutor()實質(zhì)是LinkedBlockingQueue剃诅,創(chuàng)建了一個阻塞的安全線程隊列巷送,F(xiàn)IFO先進先出,所以可以達到線程有序執(zhí)行的目的矛辕。

推薦閱讀

談?wù)凧ava中hashCode和equals方法
談?wù)凧ava中==和equals到底有啥區(qū)別
從月薪5千到月薪3萬笑跛,優(yōu)秀的程序員

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末付魔,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子飞蹂,更是在濱河造成了極大的恐慌几苍,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,548評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件陈哑,死亡現(xiàn)場離奇詭異妻坝,居然都是意外死亡,警方通過查閱死者的電腦和手機惊窖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評論 3 399
  • 文/潘曉璐 我一進店門刽宪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人界酒,你說我怎么就攤上這事圣拄。” “怎么了毁欣?”我有些...
    開封第一講書人閱讀 167,990評論 0 360
  • 文/不壞的土叔 我叫張陵庇谆,是天一觀的道長。 經(jīng)常有香客問我凭疮,道長族铆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,618評論 1 296
  • 正文 為了忘掉前任哭尝,我火速辦了婚禮哥攘,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘材鹦。我一直安慰自己逝淹,他們只是感情好,可當我...
    茶點故事閱讀 68,618評論 6 397
  • 文/花漫 我一把揭開白布桶唐。 她就那樣靜靜地躺著栅葡,像睡著了一般。 火紅的嫁衣襯著肌膚如雪尤泽。 梳的紋絲不亂的頭發(fā)上欣簇,一...
    開封第一講書人閱讀 52,246評論 1 308
  • 那天,我揣著相機與錄音坯约,去河邊找鬼熊咽。 笑死,一個胖子當著我的面吹牛闹丐,可吹牛的內(nèi)容都是我干的横殴。 我是一名探鬼主播,決...
    沈念sama閱讀 40,819評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼卿拴,長吁一口氣:“原來是場噩夢啊……” “哼衫仑!你這毒婦竟也來了梨与?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,725評論 0 276
  • 序言:老撾萬榮一對情侶失蹤文狱,失蹤者是張志新(化名)和其女友劉穎粥鞋,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瞄崇,經(jīng)...
    沈念sama閱讀 46,268評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡陷虎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,356評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了杠袱。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片尚猿。...
    茶點故事閱讀 40,488評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖楣富,靈堂內(nèi)的尸體忽然破棺而出凿掂,到底是詐尸還是另有隱情,我是刑警寧澤纹蝴,帶...
    沈念sama閱讀 36,181評論 5 350
  • 正文 年R本政府宣布庄萎,位于F島的核電站,受9級特大地震影響塘安,放射性物質(zhì)發(fā)生泄漏糠涛。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,862評論 3 333
  • 文/蒙蒙 一兼犯、第九天 我趴在偏房一處隱蔽的房頂上張望忍捡。 院中可真熱鬧,春花似錦切黔、人聲如沸砸脊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽凌埂。三九已至,卻和暖如春诗芜,著一層夾襖步出監(jiān)牢的瞬間瞳抓,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評論 1 272
  • 我被黑心中介騙來泰國打工伏恐, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留孩哑,地道東北人。 一個月前我還...
    沈念sama閱讀 48,897評論 3 376
  • 正文 我出身青樓脐湾,卻偏偏與公主長得像臭笆,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子秤掌,可洞房花燭夜當晚...
    茶點故事閱讀 45,500評論 2 359

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

  • Java SE 基礎(chǔ): 封裝愁铺、繼承、多態(tài) 封裝: 概念:就是把對象的屬性和操作(或服務(wù))結(jié)合為一個獨立的整體闻鉴,并盡...
    Jayden_Cao閱讀 2,111評論 0 8
  • 前言 最近金三銀四茵乱,相信不少朋友都在躍躍欲動,看看市場機會孟岛,此份Java整理是平安科技(陸金所)項目組大神整理的J...
    蘇村的南哥閱讀 811評論 0 2
  • 1 多線程--初步 【 1進程 進程就是在系統(tǒng)中正在運行的程序 比如:QQ瓶竭、迅雷、360渠羞、飛秋... 注意:操...
    征程_Journey閱讀 851評論 0 0
  • java筆記第一天 == 和 equals ==比較的比較的是兩個變量的值是否相等斤贰,對于引用型變量表示的是兩個變量...
    jmychou閱讀 1,504評論 0 3
  • **1.讀書筆記:Android開發(fā)進階,從小工到專家次询,ThinkinJava2.參考blog3.http://w...
    石器時代小古董閱讀 556評論 0 1