Java多線程(02)多線程的簡單使用:Thread弛矛、Runnable够吩、Callable

想學(xué)習(xí)技術(shù)一般是先知其然然后知其所以然。所以下面會討論到簡單的使用丈氓。






main線程

一個進(jìn)程正在運行時周循,至少會有一個線程在運行。Java也是這樣万俗。比如我們啟動一個Java項目湾笛,會調(diào)用mian方法,調(diào)用main方法的線程就是這樣闰歪,而且它是由JVM創(chuàng)建的嚎研。例如:

在控制臺輸出的main其實就是一個名叫mian的線程在執(zhí)行main方法中的代碼,另外课竣,控制臺輸出的main和main方法本身沒有任何關(guān)系嘉赎,僅僅是名字相同而已。因為我們可以為線程設(shè)置個性化名字于樟。而且main方法也可以調(diào)用線程執(zhí)行其他代碼公条。.上面只是簡單看了一個mian方法的線程名字,下面介紹Java幾種常見的線程實現(xiàn)方式迂曲。





繼承Thread類

在JDK中已經(jīng)自帶了對多線程技術(shù)的支持靶橱。可以很方便進(jìn)行多線程編程。下面看實現(xiàn)多線程的第一種方式关霸,繼承Thread類传黄。

Thread類位于java.lang包中,是Java1.0就有的類队寇。先看一下類的定義:

可以看到類繼承了Runnable接口膘掰,它們之間是有多態(tài)關(guān)系的,這個接口后面會講到佳遣。我們先寫一個小例子看看用法识埋。

上面的類繼承了Thread,覆蓋了一個run方法零渐,并在其中輸出了一行文字窒舟,在main方法中,調(diào)用start方法執(zhí)行了這個線程诵盼。從輸出可以看出惠豺,run方法執(zhí)行的比較晚,這樣說明在使用多線程技術(shù)時风宁,代碼運行結(jié)果與代碼執(zhí)行或者調(diào)用順序是無關(guān)的洁墙。

線程是一個子任務(wù),cup以不確定的方式杀糯,或者說隨機(jī)的時間來調(diào)用線程中的run方法扫俺,所以先打印結(jié)束在打印名字。

注意固翰,線程結(jié)束后不能再次調(diào)用線程狼纬,否則會出現(xiàn)異常:java.lang.IllegalThreadStateException

下面通過一個更加直觀的例子演示線程的隨機(jī)性。

可以看到是個線程的結(jié)果并不是按照0到9的順序執(zhí)行的骂际,與代碼的順序無關(guān)疗琉。同樣可以看出,調(diào)用start方法的順序也不代表線程的啟動順序歉铝。

在Thread類中盈简,start()方法通知“線程規(guī)劃器”此線程已經(jīng)準(zhǔn)備就緒,等待調(diào)用線程對象的run方法太示,這個過程其實就是讓系統(tǒng)安排一個時間來調(diào)用Thread中的run()方法柠贤,使線程得到運行,因此啟動線程类缤,具有異步的效果臼勉。很多人在使用Thread的時候回調(diào)用run方法執(zhí)行,如果調(diào)用run方法就是僅僅調(diào)用了一個方法而已餐弱,并不是異步宴霸,此線程對象并不交給線程規(guī)劃器處理囱晴。而是由主線程main調(diào)用run方法執(zhí)行,是同步操作瓢谢,這也是run和start的區(qū)別畸写。







實現(xiàn)Runnable接口

使用Thread類最大的局限就是實現(xiàn)方式,因為Java是單繼承氓扛,如果去繼承Thread類枯芬,那么就不能再去繼承其它類實現(xiàn)具體業(yè)務(wù) ,多以完全可以使用實現(xiàn)Runnable接口的方式實現(xiàn)多線程采郎。Thread類本身也是實現(xiàn)了Runnable接口破停,所以這兩種方式創(chuàng)建的線程在工作時性質(zhì)是一樣的。下面先看一下Runnable接口的源碼:

類里面只有一個run方法尉剩,是很多多線程類的基礎(chǔ)類。Runnable接口也在java.lang包下面毅臊,是從jdk1.0就開始有的基礎(chǔ)類理茎。下面看一個實現(xiàn)此接口的小例子:

如何使用Runnable呢?這就要看一下Thread類的構(gòu)造函數(shù)了:

在Thread類的9個構(gòu)造函數(shù)中管嬉,有兩個分別是 Thread(Runnable target)和Thread(Runnable target, String name)皂林,這兩個可以傳遞Runnable接口,可以想到使用方法如下:

從運行結(jié)果可以看到?jīng)]有什么特殊之處蚯撩。傳入的r2也是自定義了線程的名字础倍。另外需要說明的是,Thread類也實現(xiàn)了Runnable接口胎挎,所以這兩個構(gòu)造函數(shù)不見可以傳入Runnable接口沟启,還可以傳入一個Thread實例對象,這樣就實現(xiàn)了一個線程的run方法交由另一個線程去調(diào)用運行犹菇。





實現(xiàn)Callable<V>接口

Callable接口是JDK1.5之后有的線程實現(xiàn)方式德迹。我們先看一下源碼:

這個類位于java.util.concurrent包中,也即是常說的juc中揭芍。接口名稱中帶著泛型胳搞,call方法的返回類型也是泛型,說明這是一個可以有返回值的多線程實現(xiàn)方式称杨,這是與前面兩種實現(xiàn)的本質(zhì)上的區(qū)別肌毅。下面先看一個例子:

可以看到,接口的實現(xiàn)本質(zhì)上沒什么區(qū)別姑原。那么這個接口怎么運行呢悬而?顯然通過Thread類的構(gòu)造方法可以看到,不能使用Thread類页衙。Runnable接口有對應(yīng)的實現(xiàn)類Thread摊滔,可以想到Callable接口應(yīng)該也有一個阴绢,沒錯,就是FutureTask類艰躺。先看一下調(diào)用方法:

從運行結(jié)果可以看到成功獲取了線程的運行結(jié)果呻袭。獲取線程返回值的多線程實現(xiàn)方式比上面的Thread和Runnable方式要復(fù)雜一些,包含了JDK1.6以后新增的幾個接口和類腺兴,當(dāng)然Callable是基礎(chǔ)左电。下面一個一個介紹。

首先看一下Future接口:

這個接口是1.5以后出現(xiàn)的页响,可以傳入泛型篓足,用來做什么呢?那就要看一下接口中定義的幾個方法:

可以看到接口中包含了五個方法cancel闰蚕,isCancelled栈拖,isDone,get没陡,get(long涩哟,TimeUnit),弄明白這五個方法的意思大概也就知道這個接口的作用盼玄。

Future就是對于具體的Runnable或者Callable任務(wù)的執(zhí)行結(jié)果進(jìn)行取消贴彼、查詢是否完成、獲取結(jié)果埃儿。必要時可以通過get方法獲取執(zhí)行結(jié)果器仗,該方法會阻塞直到任務(wù)返回結(jié)果。這是定義Future接口的作用童番。五個方法說明如下:

cancel方法用來取消任務(wù)精钮,如果取消任務(wù)成功則返回true,如果取消任務(wù)失敗則返回false妓盲。參數(shù)mayInterruptIfRunning表示是否允許取消正在執(zhí)行卻沒有執(zhí)行完畢的任務(wù)杂拨,如果設(shè)置true,則表示可以取消正在執(zhí)行過程中的任務(wù)悯衬。如果任務(wù)已經(jīng)完成弹沽,則無論mayInterruptIfRunning為true還是false,此方法肯定返回false筋粗,即如果取消已經(jīng)完成的任務(wù)會返回false策橘;如果任務(wù)正在執(zhí)行,若mayInterruptIfRunning設(shè)置為true娜亿,則返回true丽已,若mayInterruptIfRunning設(shè)置為false,則返回false买决;如果任務(wù)還沒有執(zhí)行沛婴,則無論mayInterruptIfRunning為true還是false吼畏,肯定返回true。

isCancelled方法表示任務(wù)是否被取消成功嘁灯,如果在任務(wù)正常完成前被取消成功泻蚊,則返回 true。

isDone方法表示任務(wù)是否已經(jīng)完成丑婿,若任務(wù)完成性雄,則返回true;

get()方法用來獲取執(zhí)行結(jié)果羹奉,這個方法會產(chǎn)生阻塞秒旋,會一直等到任務(wù)執(zhí)行完畢才返回;

get(long timeout, TimeUnit unit)用來獲取執(zhí)行結(jié)果诀拭,如果在指定時間內(nèi)迁筛,還沒獲取到結(jié)果,就直接返回null耕挨。


也就是說Future提供了三種功能:

  1)判斷任務(wù)是否完成瑰煎;

  2)能夠中斷任務(wù);

  3)能夠獲取任務(wù)執(zhí)行結(jié)果俗孝。

因為Future只是一個接口,所以是無法直接用來創(chuàng)建對象使用的魄健,因此就有了的FutureTask赋铝。


在看FutureTask之前,要先看一個接口RunnableFuture:

這個接口就比較簡單了沽瘦,繼承了兩個接觸接口革骨,并定義了一個run方法,RunnableFuture?繼承了Runnable析恋, Future良哲,表示可以帶有返回值的run接口。


看完上面兩個接口的結(jié)構(gòu)助隧,最后看看FutureTask類:

從1.5開始有的類筑凫,實現(xiàn)了RunnableFuture,再看一下方法:

可以看到并村,這個類的方法大部分是實現(xiàn)了上面幾個接口的方法巍实,并對線程的結(jié)果加了處理方法。現(xiàn)在可以總結(jié)出哩牍,RunnableFuture繼承了Runnable接口和Future接口棚潦,而FutureTask實現(xiàn)了RunnableFuture接口。所以它既可以作為Runnable被線程執(zhí)行膝昆,又可以作為Future得到Callable的返回值丸边。這就是帶有返回值的多線程的實現(xiàn)方式叠必。這幾個新增的類都在juc包中。為什么可以獲取返回值妹窖,后面會詳細(xì)分析源碼纬朝。? ? ?


上面介紹了JDK中三種多線程的實現(xiàn)方式,已經(jīng)底層接口和類的繼承實現(xiàn)關(guān)系嘱吗,只是三個使用的小例子玄组。


代碼地址:https://gitee.com/blueses/java-threads-demo? 01? 02? 03



















我們的交流基地,“JAVA互聯(lián)網(wǎng)技術(shù)交流:789650498”歡迎小伙伴們一起來交流:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末谒麦,一起剝皮案震驚了整個濱河市俄讹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌绕德,老刑警劉巖患膛,帶你破解...
    沈念sama閱讀 221,888評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異耻蛇,居然都是意外死亡踪蹬,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評論 3 399
  • 文/潘曉璐 我一進(jìn)店門臣咖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來跃捣,“玉大人,你說我怎么就攤上這事夺蛇【纹幔” “怎么了?”我有些...
    開封第一講書人閱讀 168,386評論 0 360
  • 文/不壞的土叔 我叫張陵刁赦,是天一觀的道長娶聘。 經(jīng)常有香客問我,道長甚脉,這世上最難降的妖魔是什么丸升? 我笑而不...
    開封第一講書人閱讀 59,726評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮牺氨,結(jié)果婚禮上狡耻,老公的妹妹穿的比我還像新娘。我一直安慰自己猴凹,他們只是感情好酝豪,可當(dāng)我...
    茶點故事閱讀 68,729評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著精堕,像睡著了一般孵淘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上歹篓,一...
    開封第一講書人閱讀 52,337評論 1 310
  • 那天瘫证,我揣著相機(jī)與錄音揉阎,去河邊找鬼。 笑死背捌,一個胖子當(dāng)著我的面吹牛毙籽,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播毡庆,決...
    沈念sama閱讀 40,902評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼坑赡,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了么抗?” 一聲冷哼從身側(cè)響起毅否,我...
    開封第一講書人閱讀 39,807評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蝇刀,沒想到半個月后螟加,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,349評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡吞琐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,439評論 3 340
  • 正文 我和宋清朗相戀三年捆探,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片站粟。...
    茶點故事閱讀 40,567評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡黍图,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出奴烙,到底是詐尸還是另有隱情雌隅,我是刑警寧澤,帶...
    沈念sama閱讀 36,242評論 5 350
  • 正文 年R本政府宣布缸沃,位于F島的核電站,受9級特大地震影響修械,放射性物質(zhì)發(fā)生泄漏趾牧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,933評論 3 334
  • 文/蒙蒙 一肯污、第九天 我趴在偏房一處隱蔽的房頂上張望翘单。 院中可真熱鬧,春花似錦蹦渣、人聲如沸哄芜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽认臊。三九已至,卻和暖如春锄奢,著一層夾襖步出監(jiān)牢的瞬間失晴,已是汗流浹背剧腻。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留涂屁,地道東北人书在。 一個月前我還...
    沈念sama閱讀 48,995評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像拆又,于是被迫代替她去往敵國和親儒旬。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,585評論 2 359