Java中Thread和Runnable創(chuàng)建線程的方式對比
一、通過繼承Thread創(chuàng)建線程
通過繼承Thread類,創(chuàng)建一個線程,在主線程中,調(diào)用start,讓線程處于runnable狀態(tài),讓系統(tǒng)去運行線程的方法。
public class MyThread extends Thread {
@Override
public void run() {
System.out.println("執(zhí)行線程");
}
}
public class ThreadTest {
public static void main(String[] args) {
Thread thread = new MyThread();
thread.start();
}
}
二、實現(xiàn)Runnable創(chuàng)建檢查
通過實現(xiàn)runnable接口,創(chuàng)建一個線程,需要把runnable的實現(xiàn)類,作為Thread的構(gòu)造方法的參數(shù),運行這個線程。
public class MyThread implements Runnable {
@Override
public void run() {
System.out.println("執(zhí)行線程");
}
}
public class ThreadTest {
public static void main(String[] args) {
Runnable thread = new MyThread();
Thread thread1 = new Thread(thread);
thread1.start();
}
}
這里要注意一些,runnable的實現(xiàn)類,是沒有start()方法的,只有run()方法

如果運行這個run方法,依然能運行線程的方法,但是,這個方法并不是在新的線程中運行的,而是在主線程中運行的。
public class MyThread implements Runnable {
@Override
public void run() {
System.out.println("此方法在:"+Thread.currentThread().getName()+"中運行");
}
}
public class ThreadTest {
public static void main(String[] args) {
Runnable run = new MyThread();
System.out.println("此方法在:"+Thread.currentThread().getName()+"中執(zhí)行");
run.run();
// Thread thread1 = new Thread(run);
// thread1.start();
}
}
運行結(jié)果:

如果把注釋打開,run()注釋掉,結(jié)果如下:

三、比較兩種創(chuàng)建方式
3.1、多繼承
Java是不支持類的多繼承的,但是支持接口的多實現(xiàn),所以Runnable在使用上更加靈活。
3.2、 數(shù)據(jù)共享
如果一個類繼承Thread,則不適合資源共享。但是如果實現(xiàn)了Runable接口的話,則很容易的實現(xiàn)資源共享。
如果線程中有一個成員變量,使用Runnable創(chuàng)建的線程,多個線程之間可以共同訪問這個變量,而Thread不可以。

為什么呢?一個Thread創(chuàng)建的線程,每次都是new的一個新的線程對象,線程對象之間的成員變量不共享。而Runnale,可以作為Thread類的參數(shù),可以多創(chuàng)建幾個Thread類,把Runnale作為參數(shù),讓多個線程一起運行。
public class ThreadTest {
public static void main(String[] args) {
Runnable run = new MyThread();
Thread thread1 = new Thread(run);
Thread thread2 = new Thread(run);
Thread thread3 = new Thread(run);
thread1.start();
thread2.start();
thread3.start();
}
}
3.3、線程池
線程池只能放入實現(xiàn)Runable或callable類線程,不能直接放入繼承Thread的類。

四、源碼分析
當(dāng)我們進入Thread方法,可以看的Thread也實現(xiàn)了Runnable接口

使用Thread肯定也實現(xiàn)了他的run方法。

可以看出,在這個run方法中,如果target不為空,執(zhí)行target的run方法,那target是什么?

進入后,發(fā)現(xiàn)是runnable接口,那它是如何初始化的?突然想起,執(zhí)行runnable的實現(xiàn)類時,都會把他通過構(gòu)造函數(shù)傳遞,那來看看構(gòu)造函數(shù)。

繼續(xù)往下,可以看出確實是在這里初始化的。

所以,Runnbale接口的run方法,是通過Thread的成員變量去執(zhí)行的。
到此這篇關(guān)于Java中Thread和Runnable創(chuàng)建線程的方式對比的文章就介紹到這了,更多相關(guān)Java中Thread和Runnable創(chuàng)建線程內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java實現(xiàn)基于TCP協(xié)議網(wǎng)絡(luò)socket編程(C/S通信)
這篇文章主要介紹了java實現(xiàn)基于TCP協(xié)議網(wǎng)絡(luò)socket編程(C/S通信),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10
servlet監(jiān)聽器的學(xué)習(xí)使用(三)
這篇文章主要為大家詳細(xì)介紹了servlet監(jiān)聽器學(xué)習(xí)使用的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-09-09
SpringBoot Actuator監(jiān)控的項目實踐
本文主要結(jié)合 Spring Boot Actuator,跟大家一起分享微服務(wù)Spring Boot Actuator 的常見用法,方便我們在日常中對我們的微服務(wù)進行監(jiān)控治理,感興趣的可以了解一下2024-01-01

