先記住一句話:線程操作資源類
一应役、Java使用多線程主要有三種方式:
第一種:繼承Thread類
步驟:
① 定義一個類,繼承Thread類燥筷,并重寫Thead類的run方法箩祥,run方法內(nèi)的內(nèi)容為該線程要執(zhí)行的任務(wù)。run方法也被稱為執(zhí)行體肆氓。
② 創(chuàng)建Thead子類的實例袍祖,即創(chuàng)建線程對象。
③ 使用線程的start方法啟動線程谢揪。
第二種:實現(xiàn)Runnable方法蕉陋,Java8以后可以結(jié)合lambda表達式使用(Runnable接口的實現(xiàn)類并不是線程類捐凭,只是線程運行的目標類,即線程要干的事兒凳鬓,執(zhí)行線程還需要依賴Thread類)
步驟:
① 定義一個類茁肠,實現(xiàn)Runnable接口,并重寫該接口的run方法缩举,run方法體仍然是執(zhí)行體垦梆。
② 創(chuàng)建一個Thead類的實例,并將實現(xiàn)Runnable接口的類的實例作為參數(shù)傳入Thead類的構(gòu)造器中蚁孔。
③ 調(diào)用Thread類實例的start方法啟動線程奶赔。
第三種:實現(xiàn)Callable接口(需使用Future接口的實現(xiàn)類配合)
步驟:
① 定義一個類A,實現(xiàn)Callable接口杠氢,并重寫該接口的call方法站刑,call方法體仍然是執(zhí)行體,call方法有返回值鼻百。
② 創(chuàng)建實現(xiàn)Callable接口的類A的實例B绞旅,并使用Future接口的實現(xiàn)類FutureTask子類包裝B,F(xiàn)utureTask對象封裝了B的call方法的返回值温艇。
③ 創(chuàng)建一個Thead類的實例因悲,并將FutureTask的類的實例作為參數(shù)傳入Thead類的構(gòu)造器中。
④ 調(diào)用Thread類實例的start方法啟動線程勺爱。
⑤ 需要時晃琳,調(diào)用FutureTask類的實例的get方法獲取call方法的返回值。
二琐鲁、創(chuàng)建線程的三種方式的對比
采用實現(xiàn)Runnable卫旱、Callable接口的方式創(chuàng)建多線程時,優(yōu)勢是:
線程類只是實現(xiàn)了Runnable接口或Callable接口围段,還可以繼承其他類(java類可實現(xiàn)多個接口顾翼,但只能繼承一個父類)。
在這種方式下奈泪,多個線程可以共享同一個target對象适贸,所以非常適合多個相同線程來處理同一份資源的情況,從而可以將CPU涝桅、代碼和數(shù)據(jù)分開拜姿,形成清晰的模型,較好地體現(xiàn)了面向?qū)ο蟮乃枷搿?/p>
劣勢是:
編程稍微復(fù)雜冯遂,如果要訪問當(dāng)前線程蕊肥,則必須使用Thread.currentThread()方法。
使用繼承Thread類的方式創(chuàng)建多線程時優(yōu)勢是:
編寫簡單债蜜,如果需要訪問當(dāng)前線程晴埂,則無需使用Thread.currentThread()方法究反,直接使用this即可獲得當(dāng)前線程。
劣勢是:
線程類已經(jīng)繼承了Thread類儒洛,所以不能再繼承其他父類精耐。
三、使用線程池執(zhí)行操作
jdk1.5之后新增的java.util.concurrent包中提供了很多種線程池的實現(xiàn):
可以使用 Executors 進行創(chuàng)建琅锻,只需創(chuàng)建線程對象卦停,放入調(diào)用ExecutorService的execute方法并將創(chuàng)建的線程對象傳入即可(推薦使用線程池的submit方法,因為submit方法可以提交實現(xiàn)Callable接口的類),無需用戶再手動啟動線程恼蓬,同時可以提高線程的利用率惊完。上述都是舊的使用方式了,因為線程池中無界隊列可能導(dǎo)致內(nèi)存溢出的問題处硬,不想被領(lǐng)導(dǎo)爆錘小槐,就按照阿里規(guī)范來,其中明確要求線程池的使用要自己創(chuàng)建并指定隊列長度荷辕。
另外提一下線程池的體系結(jié)構(gòu):
java.util.concurrent.Executor : 負責(zé)線程的執(zhí)行和調(diào)度的根接口
||-- **ExecutorService 子接口 : 線程池的主要接口
||-- ThreadPoolExecutor : 線程池的實現(xiàn)類
||-- ScheduleExecutorService 子接口:負責(zé)線程的調(diào)度
||-- ScheduledThreadPoolExecutor : 繼承ThreadPoolExecutor 實現(xiàn) ScheduleExecutorService