從我實(shí)習(xí)面試開始就有在面試中遇到過這個(gè)問題:創(chuàng)建線程有幾種方法
記得當(dāng)時(shí)的回答是:在jdk1.5之后有三種創(chuàng)建方式
1.繼承Thread類
2.實(shí)現(xiàn)Runnable接口
3.實(shí)現(xiàn)Callable接口
工作之后回顧這個(gè)問題就會(huì)想到器罐,這三種方式的不同點(diǎn)在哪呢晴裹?所有有了探究的這篇文章
雖然網(wǎng)上已經(jīng)有很多文章珠玉在前楷怒,但是我還是想寫一篇我自己的文章炼蹦,如果寫的不好逮壁,請(qǐng)見諒
先來實(shí)現(xiàn)最基本的創(chuàng)建線程的三種方式吧
1.繼承Thread類
/**
* @author miao
*/
public class ThreadDemo extends Thread {
private final String threadName;
public ThreadDemo(String threadName) {
this.threadName = threadName;
}
@Override
public void run() {
System.out.println(threadName + Thread.currentThread().getName());
}
public static void main(String[] args) {
// 多線程級(jí)別調(diào)用
new ThreadDemo("test thread demo:").start();
// 方法級(jí)別的調(diào)用
new ThreadDemo("test thread demo:").run();
}
}
2.實(shí)現(xiàn)Runnable接口
/**
* @author miao
*/
public class RunnableDemo implements Runnable {
@Override
public void run() {
System.out.println("RunnableDemo:" + Thread.currentThread().getName());
}
public static void main(String[] args) {
Thread thread = new Thread(new RunnableDemo());
thread.start();
}
}
3.實(shí)現(xiàn)Callable接口
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
/**
* @author miao
*/
public class FutureTaskDemo implements Callable<String> {
@Override
public String call() throws Exception {
return "return callable demo";
}
public static void main(String[] args) throws Exception {
FutureTask task = new FutureTask(new FutureTaskDemo());
new Thread(task).start();
System.out.println(task.get());
}
}
已經(jīng)完成了三種創(chuàng)建線程的方式了颓遏,那么我們就來思考一下這三種方式的相同點(diǎn)和不同點(diǎn)吧
其實(shí)關(guān)于最常見面試題的就是:Runnable與Callable的不同點(diǎn)是什么徐矩?
一般同學(xué)會(huì)回答:Runnable無返回值,而Callable有返回值能拋異常
其實(shí)叁幢,這三種創(chuàng)建線程的方式本質(zhì)上是一樣的B说啤!B妗鳞骤!不信的話看我證明吧
首先是第一種方式,繼承Thread
類黍判,點(diǎn)開這個(gè)類我們可以看到豫尽,其實(shí)Thread
實(shí)現(xiàn)了Runnable
接口,重寫了run()
方法
在這里插入圖片描述
在這里插入圖片描述
第二種方法我們就不說了顷帖,因?yàn)樗旧砭褪菍?shí)現(xiàn)的Runnable
接口美旧,我們繼續(xù)來看第三種實(shí)現(xiàn)Callable的接口。
首先我們要看的是FutureTask<V>
贬墩,實(shí)現(xiàn)了RunnableFuture<V>
接口榴嗅,再點(diǎn)開RunnableFuture<V>
接口看,繼承了
Runnable
,Future<V>
接口陶舞,所以說到底還是與Runnable
接口有關(guān)
在這里插入圖片描述
在這里插入圖片描述
其實(shí)文章到這里就可以結(jié)束了嗽测,但是我看到第三種Callable
方法中能通過get()
獲取到返回值,那又是在什么時(shí)候set
進(jìn)去的呢肿孵?
為此我點(diǎn)開了FutureTask
的run()
方法查找結(jié)果论咏,答案如下,在調(diào)用完call()
方法后颁井,執(zhí)行set(result)
進(jìn)去厅贪,所以我們后面能通過get()
方法獲取到result
在這里插入圖片描述