JAVA中建立線程的三種方法及比較

 

  JAVA中建立線程的方式有三種,各有優缺點,具體以下:編程

 

1、繼承Thread類來建立線程多線程

一、建立一個任務類,繼承Thread線程類,由於Thread類已經實現了Runnable接口,而後重寫run()方法,run()方法中的內容就是須要線程完成的任務。this

二、建立一個任務類的對象,即建立了線程對象。spa

三、調用任務類對象的start()方法,來啓動一個線程。線程

代碼實例:code

 1 public class TestThread extends Thread {
 2     public void run() {
 3         for (int i = 0; i < 20; i++) {
 4             // 與Thread.currentThread().getName()相同
 5             System.out.println(this.getName() + " " + i);
 6         }
 7     }
 8 
 9     public static void main(String[] args) {
10         TestThread t1 = new TestThread();
11         TestThread t2 = new TestThread();
12         t1.start();
13         t2.start();
14     }
15 }

 

2、實現Runnable接口來建立線程對象

一、建立一個任務類,實現Runnable接口,並實現run()方法,run()方法中的內容就是須要線程完成的任務。blog

二、建立一個任務類的對象。繼承

三、任務類必須在線程中執行,所以將任務類的對象做爲參數,建立一個Thread類對象,該Thread類對象纔是真正的線程對象。接口

四、調用Thread線程類對象的start()方法,來啓動一個線程。

代碼實例:

 1 public class TestThread implements Runnable {
 2     public void run() {
 3         for (int i = 0; i < 20; i++) {
 4             // 獲取線程名稱,默認格式:Thread-0
 5             System.out.println(Thread.currentThread().getName() + " " + i);
 6         }
 7     }
 8 
 9     public static void main(String[] args) {
10         TestThread tt1 = new TestThread();
11         TestThread tt2 = new TestThread();
12         // 可爲線程添加名稱:Thread t1 = new Thread(tt1, "線程1");
13         Thread t1 = new Thread(tt1);
14         Thread t2 = new Thread(tt2);
15         t1.start();
16         t2.start();
17     }
18 }

 

3、經過Callable和Future來建立線程

一、建立一個任務類,實現Callable接口,並實現call()方法,call()方法中的內容就是須要線程完成的任務,且有返回值。

二、建立一個任務類的對象,並使用FutureTask類來包裝任務類的對象,該FutureTask對象封裝了任務類對象中call()方法的返回值。

三、任務類必須在線程中執行,所以將FutureTask類的對象做爲參數,建立一個Thread類對象,該Thread類對象纔是真正的線程對象。

四、調用Thread線程類對象的start()方法,來啓動一個線程。

五、調用FutureTask類對象的get()方法來獲取線程執行的返回值,即任務類對象中call()方法的返回值。

代碼實例:

 1 public class TestThread implements Callable<Integer> {
 2     public Integer call() {
 3         int i = 0;
 4         for (i = 0; i < 20; i++) {
 5             if (i == 5)
 6                 break;
 7             System.out.println(Thread.currentThread().getName() + " " + i);
 8         }
 9         return i;
10     }
11 
12     public static void main(String[] args) {
13         TestThread tt = new TestThread();
14         FutureTask<Integer> ft = new FutureTask<Integer>(tt);
15         Thread t = new Thread(ft);
16         t.start();
17         try {
18             System.out.println(Thread.currentThread().getName() + " " + ft.get());
19         } catch (Exception e) {
20             e.printStackTrace();
21         }
22     }
23 }

 

4、三種方式建立線程的比較

一、繼承Thread類方式:

(1)優勢:編寫簡單,任務類中訪問當前線程時,能夠直接使用this關鍵字。

(2)缺點:任務類即線程類已經繼承了Thread類,因此不能再繼承其餘父類。

二、實現Runnable接口的方式:

(1)優勢:任務類只實現了Runnable接口,還能夠繼承其餘類。這種方式,能夠多個線程對象共享一個任務類對象,即多線程共享一份資源的狀況,以下:

1     TestThread tt1 = new TestThread();
2     Thread t1 = new Thread(tt1);
3     Thread t2 = new Thread(tt1);
4     t1.start();
5     t2.start();

(2)缺點:編寫稍微複雜,任務類中訪問當前線程時,必須使用Thread.currentThread()方法。

三、經過Callable和Future的方式:

(1)優勢:任務類只實現了Callable接口,還能夠繼承其餘類,一樣多線程下可共享同一份資源,這種方式還有返回值,而且能夠拋出返回值的異常。

(2)缺點:編寫稍微複雜,任務類中訪問當前線程時,必須使用Thread.currentThread()方法。

 

  總結:在僅僅只重寫run()方法,而不重寫Thread類其餘方法的前提下,比較推薦實現Runnable接口的方式建立線程。由於不打算修改或加強類的基本能力,不該該爲其建立子類。並且實現Runnable接口的方式,線程和資源相對分離,程序更加健壯,更符合面向對象的編程思想。固然,須要線程有返回值時能夠使用Callable的方式,但Callable的方式有一個問題,當調用get()方法時,若是線程還未執行完畢,則會阻塞到線程執行完畢拿到返回值。

相關文章
相關標籤/搜索