經常看源碼的大家應該都知道,Thread中包含了start和run兩個方法,這兩個方法都是用來啓動線程的,那麼他們到底有什麼區別,我們來講一講…
是什麼??
- start()方法是什麼?
線程類的start方法可以用來啓動線程,該方法會在內部調用Runnable接口的run方法,以在單獨的線程中執行run方法中所指定的代碼
啓動線程執行的任務:- 統計一個新線程
- 線程從New state移動到Runnable狀態
- 當線程有機會執行時,他的目標run方法將運行
- run()方法是什麼??
- 線程類的run方法是Runnable接口的一個抽象方法,由虛擬機直接調用,不會創建新的線程
區別?!
start方法的作用是啓動一個新線程,新線程會執行相應的run方法,start方法不能被重複調用
run方法就和普通的成員方法一樣,可以被重複調用。單獨調用run方法的話,會在當前線程中執行run,而不會去啓動新的線程。
Public class MyThread extends Thread{
public void run(){
....//run方法實現
}
};
MyThread aaa=new MyThread();
當aaa執行start方法時,會創建一個新的線程,並在新的線程中使用run方法;而當aaa執行run方法的時候,則直接在當前線程中運行run方法,而不會啓動一個新線程來運行run方法
樣例
class MyThread extends Thread{
public MyThread(String name){
super(name);
}
public void run(){
System.out.println(Thread.currentThread().getName+"is running");
}
};
public class demo{
public static void main(String[] args){
Thread myThread=new MyThread("myThread");
System.out.println(Thread.currentThread.getName()+" call myThread.run()");
myThread.run();
System.out.println(Thread.currentThread.getName()+" call myThread.start()");
myThread.start();
}
}
執行結果:
main call myThread.run()
main is running;
main myThread.start();
myThread is running
說明:
(01) Thread.currentThread().getName()是用於獲取“當前線程”的名字。當前線程是指正在cpu中調度執行的線程。
(02) mythread.run()是在“主線程main”中調用的,該run()方法直接運行在“主線程main”上。
(03) mythread.start()會啓動“線程mythread”,“線程mythread”啓動之後,會調用run()方法;此時的run()方法是運行在“線程mythread”上。
相關源碼(jdk 8)
public synchronized void start() {
/**
* 對於主方法thread或“system”不調用此方法
* 由VM創建/設置的組線程。將來添加到這個方法中的任何新功能也可能必須添加到VM中。
*
* 零狀態值對應於狀態“新建”。
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
/*通知組此線程即將啓動,以便可以將其添加到組的線程列表中,並且可以減少組的未啓動計數 */
group.add(this);
boolean started = false;
try {
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* 什麼都不做。如果start0拋出了一個異常,那麼它將被傳遞到調用堆棧中 */
}
}
}
start()實際上是通過本地方法start0()啓動線程的。而start0()會新運行一個線程,新線程會調用run()方法。
private native void start0();
public void run() {
if (target != null) {
target.run();
}
}
target是一個Runnable對象。run()直接調用Thread線程的Runnable成員的run()方法,不會新建線程。