繼承Thread方法
package com.ljqBook.JUC;
//創建新線程第一種方式:繼承Thread類
//該方式的侷限性:Java是單根繼承,不支持多繼承
import java.util.concurrent.TimeUnit;
class MyThread extends Thread{
public void run(){
super.run();
System.out.println("MyThread");
}
}
public class Test102_ExtendsThread {
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
try{ TimeUnit.SECONDS.sleep(3);} catch(InterruptedException e){e.printStackTrace();}
System.out.println(Thread.currentThread().getName() + " + \t 運行結束...");
}
}
實現Runable接口
package com.ljqBook.JUC;
import java.util.concurrent.TimeUnit;
//實現Runnable接口
class MyRunnable implements Runnable{
@Override
public void run() {
System.out.println("MyRunnable運行中...");
}
}
public class Test103_ImplementsRunnable {
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
thread.start();
try{ TimeUnit.SECONDS.sleep(3);} catch(InterruptedException e){e.printStackTrace();}
System.out.println("main運行結束...");
}
}
大家都知道這兩種方法是創建線程的基本方法,下面我將總結兩點核心區別:
1. 執行不同
我們知道繼承Thread類,JVM直接調用的是Thread.java類的run()方法,而實現Runnable接口執行要稍微複雜一點點,通過源碼分析:
@Override
public void run(){
if(!target != null){ //target變量是啥?
this.run();
}
}
target存儲的對象就是前面聲明的MyRunnable myRunnale對象,對Thread構造方法傳入Runnable對象,再結合if判斷就可以執行run()方法了
再看看Thread.java構造方法源碼:
poublic Thread(Runnable traget){
init(null, target, "Thread-" + nextThreadNum(), 0);
}
private void init(ThreadGroup g, Runnable target, String name, long stackSize, AccessControlContext acc, boolean inheritThreadLocals){
//......
this.target = target;
//......
}
//變量target是在init()方法中進行賦值初始化的
2. 應用不同
我們知道Java是不支持多繼承的,因此使用繼承Thread類的方式在開發多線程應用程序在設計上是有侷限的。爲避免多繼承報錯,但又需要實現多線程,這個時候就是使用Runnable接口的必要性了