Java 線程調(diào)用start()后會立即執(zhí)行run()方法嗎艰躺?

別想當然

問題

Java 線程調(diào)用start()后會立即執(zhí)行run()方法嗎?

我們在開發(fā)中顿天,經(jīng)常和線程打交道泄朴,有些東西總是司空見慣,想當然地認為某些事情理所當然...
但是今天偶然發(fā)現(xiàn)一個有趣的現(xiàn)象:

class Test {
    public static void main(String[] args) {
        System.out.println("hello https://tool.lu/");

        Runnable runnable = new Runnable(){
            @Override
                public void run() {
                System.out.println("--run()--");
            }
        };

        Thread thread = new Thread(runnable);
        thread.start();
        System.out.println("--after start()--");
    }
}


運行結(jié)果如下:


運行結(jié)果

看到運行結(jié)果之后露氮,我愣了一下祖灰,WTF?
跟我想的有點不一樣啊,

理論上來講畔规,線程調(diào)用start()之后局扶,將會調(diào)用該線程的run();
我又趕緊去查看了Java的官方文檔:JavaAPI

Thread的start()

Cause this thread to begin execution ; the Java Virtual Machine calls the run method of this thread.

通過上面我們可以發(fā)現(xiàn)start()就是使該線程開始運行,JVM會調(diào)用線程的run()方法叁扫。

那我們只能從源碼中找答案啦三妈。

  /**
     * Causes this thread to begin execution; the Java Virtual Machine
     * calls the <code>run</code> method of this thread.
     * <p>
     * The result is that two threads are running concurrently: the
     * current thread (which returns from the call to the
     * <code>start</code> method) and the other thread (which executes its
     * <code>run</code> method).
     * <p>
     * It is never legal to start a thread more than once.
     * In particular, a thread may not be restarted once it has completed
     * execution.
     *
     * @exception  IllegalThreadStateException  if the thread was already
     *               started.
     * @see        #run()
     * @see        #stop()
     */
    public synchronized void start() {
        /**
         * This method is not invoked for the main method thread or "system"
         * group threads created/set up by the VM. Any new functionality added
         * to this method in the future may have to also be added to the VM.
         *
         * A zero status value corresponds to state "NEW".
         */
        // Android-changed: throw if 'started' is true
        if (threadStatus != 0 || started)
            throw new IllegalThreadStateException();

        /* Notify the group that this thread is about to be started
         * so that it can be added to the group's list of threads
         * and the group's unstarted count can be decremented. */
        group.add(this);

        started = false;
        try {
            nativeCreate(this, stackSize, daemon);
            started = true;
        } finally {
            try {
                if (!started) {
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
                /* do nothing. If start0 threw a Throwable then
                  it will be passed up the call stack */
            }
        }
    }

    private native static void nativeCreate(Thread t, long stackSize, boolean daemon);

關鍵代碼已經(jīng)貼出,但是似乎關鍵在于nativeCreate()方法莫绣。該方法屬于c方法畴蒲,有時間再追蹤一下。

思考

通過代碼測試我們發(fā)現(xiàn)線程調(diào)用start()方法对室,并不會立刻執(zhí)行run()方法模燥。但是兩者之間的時間差是多少呢?

測試用例,有興趣的朋友can have a try.

把運行結(jié)果給出來:


運行結(jié)果

通過我的多次測試掩宜,run()和start()的時間差一般都在[0,8]之內(nèi)蔫骂,當然運行足夠多次會發(fā)現(xiàn)時間差會更大。

總結(jié)

雖然該用例看似沒什么卵用牺汤,但不親自上手嘗試辽旋,還真會回答錯...有趣有趣...
需要注意的是如果我們在線程中創(chuàng)建對象,而在start()方法后直接使用該對象檐迟,就會出現(xiàn)該問題測試用例补胚。


夫小惑易方,大惑易性...

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末追迟,一起剝皮案震驚了整個濱河市溶其,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌怔匣,老刑警劉巖握联,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異每瞒,居然都是意外死亡金闽,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門剿骨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來代芜,“玉大人,你說我怎么就攤上這事浓利〖繁樱” “怎么了?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵贷掖,是天一觀的道長嫡秕。 經(jīng)常有香客問我,道長苹威,這世上最難降的妖魔是什么昆咽? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮牙甫,結(jié)果婚禮上掷酗,老公的妹妹穿的比我還像新娘。我一直安慰自己窟哺,他們只是感情好泻轰,可當我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著且轨,像睡著了一般浮声。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上旋奢,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天阿蝶,我揣著相機與錄音,去河邊找鬼黄绩。 笑死羡洁,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的爽丹。 我是一名探鬼主播筑煮,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼粤蝎!你這毒婦竟也來了真仲?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤初澎,失蹤者是張志新(化名)和其女友劉穎秸应,沒想到半個月后虑凛,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡软啼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年桑谍,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片祸挪。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡锣披,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出贿条,到底是詐尸還是另有隱情雹仿,我是刑警寧澤,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布整以,位于F島的核電站胧辽,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏公黑。R本人自食惡果不足惜票顾,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望帆调。 院中可真熱鬧奠骄,春花似錦、人聲如沸番刊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽芹务。三九已至蝉绷,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間枣抱,已是汗流浹背熔吗。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留佳晶,地道東北人桅狠。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像轿秧,于是被迫代替她去往敵國和親中跌。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,914評論 2 355

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

  • 1. Java基礎部分 基礎部分的順序:基本語法菇篡,類相關的語法漩符,內(nèi)部類的語法,繼承相關的語法驱还,異常的語法嗜暴,線程的語...
    子非魚_t_閱讀 31,631評論 18 399
  • 文章來源:http://www.54tianzhisheng.cn/2017/06/04/Java-Thread/...
    beneke閱讀 1,486評論 0 1
  • 本文主要講了java中多線程的使用方法凸克、線程同步、線程數(shù)據(jù)傳遞闷沥、線程狀態(tài)及相應的一些線程函數(shù)用法萎战、概述等。 首先講...
    李欣陽閱讀 2,454評論 1 15
  • Java多線程學習 [-] 一擴展javalangThread類 二實現(xiàn)javalangRunnable接口 三T...
    影馳閱讀 2,957評論 1 18
  • 1 2014年3月傍晚狐赡。我在龍門大排檔和狐朋狗友擼串撞鹉,吃的正嗨疟丙,公司一通電話打來颖侄,讓我立即、馬上享郊、火速趕到火車站览祖!...
    莫愁塘主閱讀 669評論 15 27