Thread類中的start和run!!!

經常看源碼的大家應該都知道,Thread中包含了start和run兩個方法,這兩個方法都是用來啓動線程的,那麼他們到底有什麼區別,我們來講一講…

是什麼??

  1. start()方法是什麼?
           線程類的start方法可以用來啓動線程,該方法會在內部調用Runnable接口的run方法,以在單獨的線程中執行run方法中所指定的代碼
           啓動線程執行的任務:
    • 統計一個新線程
    • 線程從New state移動到Runnable狀態
    • 當線程有機會執行時,他的目標run方法將運行
  2. 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()方法,不會新建線程。

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