@Slf4j
public class MyThread extends Thread{
@Override
public void run() {
// 執行緒要執行的內容
log.debug("繼承Thread方式");
}
}
public class Test1 {
public static void main(String[] args) {
new MyThread().start(); // 啟動執行緒
}
}
public class Test1 {
public static void main(String[] args) {
Thread t = new Thread(){
@Override
public void run() {
log.debug("執行緒執行");
}
};
t.start();
}
}
public class MyThread implements Runnable{
@Override
public void run() {
// 該執行緒執行內容
System.out.println("執行緒執行");
}
}
public static void main(String[] args) {
MyThread myThread = new MyThread();
Thread t1 = new Thread(myThread, "t1");
t1.start();
// jdk8 Lambda
Thread t2 = new Thread(()->{ System.out.println("t2執行");}, "t1");
t2.start();
Runnable runnable = ()->{ System.out.println("t3執行"); };
Thread t3 = new Thread(runnable, "t3");
t3.start();
}
Runnable的執行需要傳入Thread中執行
Runnable runnable = ()->{ System.out.println("t3執行"); };
Thread t3 = new Thread(runnable, "t3");
t3.start();
點開Thread原始碼發現會把Runnable傳個init方法
發現init又傳給另外一個init
該init方法中發現他又傳給了自身的一個變數
發現在Thread類中的run()方法最終呼叫了這個Runnable的run方法
Runnable的run最終還是走的Thread的run,如果不重新run方法的情況下Thread的run方法會優先判斷是否有Runnable傳入,如果有那麼就執行Runnable的run方法
FutureTask本身實現RunnableFuture
public class FutureTask<V> implements RunnableFuture<V>
RunnableFuture 又多繼承了Runnable和Future
public interface RunnableFuture<V> extends Runnable, Future<V>
也就是說FutureTask也可以看做一個Runnable但是又強於Runnable
因為還繼承了Future中的方法賦予了它獲取執行緒執行結果的能力
Callable只是一個介面其call 和 Runnable的run方法性質差不多,都是執行緒要執行其中的程式碼,但call有返回值的泛型同時也能做異常的丟擲,run方法就不具備異常也得內部自己消化
但我們執行程式碼的時候還是用的 start方法其還是去跑run方法,但發現我們這裡並沒有重寫run方法而是一個call方法
點開FutureTask 類,發現其內部重寫了run方法,當我們在start啟動執行緒的時候該run方法會去呼叫其傳入的Callable的call方法,並在這裡做了異常的處理並在這個時候把值返回給FutureTask的set方法供get等方法的呼叫
值返回給變數outcome
呼叫get方法的時候呼叫其report方法
該方法的返回就是run方法呼叫call的值
注意
看到get方法有返回值,也就是說他會一直阻塞到執行緒非同步的返回