創(chuàng)建線程的3種方式
一晨抡、 Thread類創(chuàng)建線程
1. 定義Thread類的子類,并重寫該類的run方法,該run方法的方法體就代表了線程要完成的任務(wù)。因此把run()方法稱為執(zhí)行體抱冷。
2. 創(chuàng)建Thread子類的實(shí)例,即創(chuàng)建了線程對象梢褐。
3. 調(diào)用線程對象的start()方法來啟動該線程旺遮。
image
二、通過Runnable接口創(chuàng)建線程
1. 定義runnable接口的實(shí)現(xiàn)類盈咳,并重寫該接口的run()方法耿眉,該run()方法的方法體同樣是該線程的線程執(zhí)行體。
2. 創(chuàng)建 Runnable實(shí)現(xiàn)類的實(shí)例鱼响,并依此實(shí)例作為Thread的target來創(chuàng)建Thread對象鸣剪,該Thread對象才是真正的線程對象。
3. 調(diào)用線程對象的start()方法來啟動該線程丈积。
image
三筐骇、通過Callable和Future創(chuàng)建線程
1. 創(chuàng)建Callable接口的實(shí)現(xiàn)類,并實(shí)現(xiàn)call()方法桶癣,該call()方法將作為線程執(zhí)行體拥褂,并且有返回值。
2. 創(chuàng)建Callable實(shí)現(xiàn)類的實(shí)例牙寞,使用FutureTask類來包裝Callable對象,該FutureTask對象封裝了該Callable對象的call()方法的返回值。
3. 使用FutureTask對象作為Thread對象的target創(chuàng)建并啟動新線程间雀。
4.啟動線程并調(diào)用FutureTask對象的get()方法來獲得子線程執(zhí)行結(jié)束后的返回值
image
優(yōu)缺點(diǎn)
使用繼承Thread類的方式創(chuàng)建多線程時優(yōu)勢是:
編寫簡單悔详,如果需要訪問當(dāng)前線程,則無需使用Thread.currentThread()方法惹挟,直接使用this即可獲得當(dāng)前線程茄螃。
劣勢是:
線程類已經(jīng)繼承了Thread類,所以不能再繼承其他父類连锯。
使用實(shí)現(xiàn)Runnable归苍、Callable接口的方式創(chuàng)見多線程時
優(yōu)勢是:線程類只是實(shí)現(xiàn)了Runnable接口或Callable接口,還可以繼承其他類运怖。
在這種方式下拼弃,多個線程可以共享同一個target對象,所以非常適合多個相同線程來處理同一份資源的情況摇展,從而可以將CPU吻氧、代碼和數(shù)據(jù)分開,形成清晰的模型咏连,較好地體現(xiàn)了面向?qū)ο蟮乃枷攵⑺铩allable接口方式創(chuàng)建線程還可以通過返回值來判斷線程執(zhí)行情況。
劣勢是:
編程稍微復(fù)雜祟滴,如果要訪問當(dāng)前線程振惰,則必須使用Thread.currentThread()方法。
關(guān)系圖
Thread關(guān)系圖
image
Runnable關(guān)系圖
image
Callable關(guān)系圖
image
Callable創(chuàng)建線程關(guān)系圖
image