摘要:昨天棧長介紹了多線程可以分組,還能這樣玩線程分組的妙用。今天,棧長會詳細(xì)介紹中的多線程和兩個方法,老司機(jī)請?zhí)^,新手或者對這兩個不是很理解的可以繼續(xù)往下看。
昨天棧長介紹了《Java多線程可以分組,還能這樣玩!》線程分組的妙用。今天,棧長會詳細(xì)介紹 Java 中的多線程 start() 和 run() 兩個方法,Java 老司機(jī)請?zhí)^,新手或者對這兩個不是很理解的可以繼續(xù)往下看。
首先要知道實現(xiàn)多線程最基本的兩種方式:
1、繼承 java.lang.Thread 類;
2、實現(xiàn) java.lang.Runnable接口;
其中 Thread 類也是實現(xiàn)了 Runnable 接口,而 Runnable 接口定義了唯一的一個 run() 方法,所以基于 Thread 和 Runnable 創(chuàng)建多線程都需要實現(xiàn) run() 方法,是多線程真正運(yùn)行的主方法。
@FunctionalInterface public interface Runnable { public abstract void run(); }
而 start() 方法則是 Thread 類的方法,用來異步啟動一個線程,然后主線程立刻返回。該啟動的線程不會馬上運(yùn)行,會放到等待隊列中等待 CPU 調(diào)度,只有線程真正被 CPU 調(diào)度時才會調(diào)用 run() 方法執(zhí)行。
所以 start() 方法只是標(biāo)識線程為就緒狀態(tài)的一個附加方法,以下 start() 方法的源碼,其中 start0() 是一個本地 native 方法。
public synchronized void start() { if (threadStatus != 0) throw new IllegalThreadStateException(); group.add(this); boolean started = false; try { start0(); 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 */ } } }
請注意,start() 方法被標(biāo)識為 synchronized 的,即為了防止被多次啟動的一個同步操作。
那么你會問了,為什么要有兩個方法,直接用一個 run() 方法不就行了嗎??? 還真不行,如果直接調(diào)用 run() 方法,那就等于調(diào)用了一個普通的同步方法,達(dá)不到多線程運(yùn)行的異步執(zhí)行,來看下面的例子。
/** * 微信公眾號:Java技術(shù)棧 */ public static void main(String[] args) { Thread thread = new Thread(() -> { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Java技術(shù)棧"); }); long start = System.currentTimeMillis(); thread.start(); System.out.println(System.currentTimeMillis() - start); start = System.currentTimeMillis(); thread.run(); System.out.println(System.currentTimeMillis() - start); }
程序輸出:
0 Java技術(shù)棧 3000 Java技術(shù)棧
從程序輸出結(jié)果可以看出,啟動 start 方法前后只用了 0 毫秒,而啟動 run 方法則阻塞了 3000 毫秒等程序執(zhí)行完再繼續(xù)執(zhí)行,這就是同步與異步的一個最重要的區(qū)別。
看完這篇,你應(yīng)該對 start 和 run 方法有了一個大概的掌握吧,再也不怕面試官問你這兩個的區(qū)別了吧!
動手轉(zhuǎn)發(fā)給更多的朋友吧!
更多 Java 多線程技術(shù)文章請在Java技術(shù)棧微信公眾號后臺回復(fù)關(guān)鍵字:多線程。
本文原創(chuàng)首發(fā)于微信公眾號:Java技術(shù)棧(id:javastack),關(guān)注公眾號在后臺回復(fù) "多線程" 可獲取更多,轉(zhuǎn)載請原樣保留本信息。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/72147.html
摘要:可能會持有相同的值對象但鍵對象必須是唯一的。當(dāng)有新任務(wù)到達(dá)時,線程池沒有線程則創(chuàng)建線程處理,處理完成后該線程緩存秒,過期后回收,線程過期前有新任務(wù)到達(dá)時,則使用緩存的線程來處理。解決死鎖問題的三種方法預(yù)防死鎖檢測死鎖及避免死鎖。 最近辭職準(zhǔn)備面試,順便整理一下面試題分享給大家,如有錯誤歡迎指出 01. 你對面向?qū)ο笏枷氲睦斫猓?面向?qū)ο缶幊毯喎QOOP,是開發(fā)程序的一種方法、思想。面向...
摘要:近段時間在準(zhǔn)備實習(xí)的面試,在網(wǎng)上看到一份面試題,就慢慢試著做,爭取每天積累一點(diǎn)點(diǎn)。現(xiàn)在每天給自己在面試題編寫的任務(wù)是題,有時候忙起來可能就沒有時間寫了,但是爭取日更,即使當(dāng)天沒更也會在之后的更新補(bǔ)上。 ????近段時間在準(zhǔn)備實習(xí)的面試,在網(wǎng)上看到一份面試題,就慢慢試著做,爭取每天積累一點(diǎn)點(diǎn)。????暫時手頭上的面試題只有一份,題量還是挺大的,有208題,所以可能講的不是很詳細(xì),只是我自...
摘要:總結(jié)的使用方法還是比較簡單的,但是我們要明白一點(diǎn)的是如果一個線程要處理消息,那么它必須擁有自己的,并不是在哪里創(chuàng)建,就可以在哪里處理消息的。如果不用的話,需要手動去調(diào)用和這些方法。 前言 前幾天看到一道面試題:Thread、Handler和HandlerThread有什么區(qū)別?,這個題目有點(diǎn)意思,對于很多人來說,可能對Thread和Handler很熟悉,主要涉及到Android的消息機(jī)...
摘要:在前面介紹的文章中,提到了關(guān)于線程池的創(chuàng)建介紹,在文章之系列外部中第一部分有詳細(xì)的說明,請參閱文章中其實說明了外部的使用方式,但是沒有說內(nèi)部是如何實現(xiàn)的,為了加深對實現(xiàn)的理解,在使用中可以放心,我們這里將做源碼解析以及反饋到原理上,工具可 在前面介紹JUC的文章中,提到了關(guān)于線程池Execotors的創(chuàng)建介紹,在文章:《java之JUC系列-外部Tools》中第一部分有詳細(xì)的說明,請參...
閱讀 2956·2023-04-26 01:52
閱讀 3481·2021-09-04 16:40
閱讀 3639·2021-08-31 09:41
閱讀 1779·2021-08-09 13:41
閱讀 575·2019-08-30 15:54
閱讀 2969·2019-08-30 11:22
閱讀 1624·2019-08-30 10:52
閱讀 957·2019-08-29 13:24