1、繼承Thread類,新建一個當前類對象,並且運行其start()方法

1 package com.xiaostudy.thread; 2 3 /** 4 * @desc 第一種開啟線程的方式 5 * @author xiaostudy 6 * 7 */ 8 public class Demo1_Thread extends Thread { 9 10 public void run() { 11 for (int i = 0; i < 10; i++) { 12 System.out.println(i + " run()..."); 13 } 14 } 15 16 public static void main(String[] args) { 17 Demo1_Thread demo = new Demo1_Thread(); 18 demo.start(); 19 for (int i = 0; i < 10; i++) { 20 System.out.println(i + " main()..."); 21 } 22 } 23 24 }
上面這里就是當前類的一個線程和main線程一起運行
2、實現Runnable接口,然后新建當前類對象,接着新建Thread對象時把當前類對象傳進去,最后運行Thread對象的start()方法

1 package com.xiaostudy.thread; 2 3 /** 4 * @desc 第二種開啟線程的方式 5 * @author xiaostudy 6 * 7 */ 8 public class Demo2_Thread implements Runnable { 9 10 public void run() { 11 for (int i = 0; i < 10; i++) { 12 System.out.println(i + " run()..."); 13 } 14 } 15 16 public static void main(String[] args) { 17 Demo2_Thread demo = new Demo2_Thread(); 18 Thread thread = new Thread(demo); 19 thread.start(); 20 for (int i = 0; i < 10; i++) { 21 System.out.println(i + " main()..."); 22 } 23 } 24 25 }
分析:
從Thread的有參構造方法進去
當前類傳進去,進入到Thread的init()方法
再跟進去
下面截圖問題,分開兩個,看行號。就把當前類賦值給了Thread的target屬性
再回過頭來看Thread對象的run()方法,因為當Thread對象的start()方法調用時,是執行Thread對象的run()方法(這里就不深入分析)
這里的target的值就是當前類對象,所以最后還是執行了當前類對象的run()方法
3、實現Callable接口,新建當前類對象,在新建FutureTask類對象時傳入當前類對象,接着新建Thread類對象時傳入FutureTask類對象,最后運行Thread對象的start()方法

package com.xiaostudy.thread; import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; /** * @desc 第三種開啟線程的方式 * @author xiaostudy * */ public class Demo3_Thread implements Callable { public static void main(String[] args) { Callable callable = new Demo3_Thread(); FutureTask futureTask = new FutureTask(callable); Thread thread = new Thread(futureTask); thread.start(); for (int i = 0; i < 10; i++) { System.out.println(i + " main()..."); } } public Object call() throws Exception { for (int i = 0; i < 10; i++) { System.out.println(i + " call()..."); } return null; } }
分析:
同樣從Thread的有參構造方法進去
同樣也是跟第二種方法一樣
那么,就看Runnable接口和FutureTask類的關系。從下面的圖看出FutureTask類是Runnable接口的繼承接口的實現類。
接着看看FutureTask的有參構造
從下圖可以看出,FutureTask的有參構造,把當前類對象傳給了FutureTask的callable屬性
那么當Thread執行start()方法時,就是執行FutureTask的run()方法,從下面圖看到,最后就是執行了當前類的call()方法