繼承Thread方法與實現Runnable接口的區別

繼承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接口的必要性了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章