Runnable接口


Runnable接口

創建線程的另一種方法是聲明實現 Runnable 接口的類。該類實現 run 方法。然后創建Runnable的子類對象,傳入到某個線程的構造方法中開啟線程。

 

實現Runnable接口的意義:Runnable接口用來指定每個線程要執行的任務。包含了一個 run 的無參數抽象方法,需要由接口實現類重寫該方法。

 

創建線程的步驟。

 

1、定義類實現Runnable接口。

 

2、覆蓋接口中的run方法。。

 

3、創建Thread類的對象

 

4、將Runnable接口的子類對象作為參數傳遞給Thread類的構造函數。

 

5、調用Thread類的start方法開啟線程。

 

//實現Runnable接口
public
class MyRunnable implements Runnable { public void run() { for(int i=0;i<100;i++){ System.out.println(Thread.currentThread().getName()+":"+i); } } }
public static void main(String[] args) { //創建線程任務對象
        MyRunnable my=new MyRunnable(); //創建線程對象
        Thread t=new Thread(my); Thread t2=new Thread(my); //開啟線程
 t.start(); t2.start(); }

 

實現Runnable的原理

 

實現Runnable接口,避免了繼承Thread類的單繼承局限性,可以多個繼承。覆蓋Runnable接口中的run方法,將線程任務代碼定義到run方法中。

創建Thread類的對象,只有創建Thread類的對象才可以創建線程。線程任務已被封裝到Runnable接口的run方法中,而這個run方法所屬於Runnable接口的子類對象,所以將這個子類對象作為參數傳遞給Thread的構造函數,這樣,線程對象創建時就可以明確要運行的線程的任務。

實現Runnable的好處

聲明實現Runnable接口避免了單繼承的局限性,所以較為常用。實現Runnable接口的方式,更加的符合面向對象思想,線程分為兩部分,一部分線程對象,一部分線程任務。繼承Thread類,線程對象和線程任務耦合在一起。一旦創建Thread類的子類對象,既是線程對象,又有線程任務。實現runnable接口,將線程任務單獨分離出來封裝成對象,類型就是Runnable接口類型。Runnable接口對線程對象和線程任務進行解耦。

 

線程的匿名內部類使用

 

public static void main(String[] args) { //繼承Thread類方式
    //此處的new Thread()方法整體就是匿名內部類,創建線程對象,可以直接重寫run()方法
new Thread(){ public void run() { for(int i=0;i<100;i++){ System.out.println(Thread.currentThread().getName()+":"+i); } } }.start(); //實現Runnable接口方式
    //此處的Runnable r=new Thread()方法整體就是匿名內部類,重寫Runnable中的run()方法
Runnable r=new Runnable(){ public void run() { for(int i=0;i<100;i++){ System.out.println(Thread.currentThread().getName()+":"+i); } } }; //創建線程對象並開啟線程 new Thread(r).start(); }

 

線程池:

線程池,其實就是一個容納多個線程的容器,其中的線程可以反復使用,省去了頻繁創建線程對象的操作,無需反復創建線程而消耗過多資源。

圖解示例:

 

 

線程池主要用來解決線程生命周期開銷問題和資源不足問題。通過對多個任務重復使用線程,線程創建的開銷就被分攤到了多個任務上了,而且由於在請求到達時線程已經存在,所以消除了線程創建所帶來的延遲。這樣,就可以立即為請求服務,使用應用程序響應更快。另外,通過適當的調整線程中的線程數目可以防止出現資源不足的情況。

 

使用線程池方式--Runnable接口

 

 

 

通常,線程池都是通過線程池工廠創建,再調用線程池中的方法獲取線程,再通過線程去執行任務方法。

 

Executors:線程池創建工廠類

 

ExecutorService:線程池類

 

Future接口:用來記錄線程任務執行完畢后產生的結果。線程池創建與使用

 

 

使用線程池中線程對象的步驟:

創建線程池對象

創建Callable接口子類對象

 

提交Callable接口子類對象

 

關閉線程池

 

public static void main(String[] args) { //獲取線程池對象
        ExecutorService es=Executors.newFixedThreadPool(2);//此處表示線程池中有2條線程 //創建線程任務對象
        MyRunnable r=new MyRunnable(); //將線程任務交給線程池執行
     //此處要有3條任務執行,而線程池只有2條,所以只能先執行前2個任務,其中一個任務執行完畢再繼續第3個任務執行
es.submit(r); es.submit(r); es.submit(r); //銷毀線程池 es.shutdown(); }

 使用線程池方式Callable接口

Callable接口:與Runnable接口功能相似,用來指定線程的任務。其中的call()方法,用來返回線程任務執行完畢后的結果,call方法可拋出異常。

ExecutorService:線程池類

 <T> Future<T> submit(Callable<T> task):獲取線程池中的某一個線程對象,並執行線程中的call()方法

Future接口:用來記錄線程任務執行完畢后產生的結果。線程池創建與使用

 

使用線程池中線程對象的步驟:

1.創建線程池對象

2.創建Callable接口子類對象

3.提交Callable接口子類對象

4.關閉線程池

 

public static void main(String[] args) throws InterruptedException, ExecutionException { //獲取線程池對象
        ExecutorService es=Executors.newFixedThreadPool(2); //創建線程任務
        MyCallable c=new MyCallable(); //將線程任務交給線程池執行
        Future<String> f=es.submit(c);
     //注意:submit方法調用結束后,程序並不終止,是因為線程池控制了線程的關閉。將使用完的線程又歸還到了線程池中
//獲取返回值 String str=f.get(); System.out.println(str); //銷毀線程池 es.shutdown(); }

 

Callable接口實現類,call方法可拋出異常、返回線程任務執行完畢后的結果

 
         
public class GetSum implements Callable<Integer> { private int num; public GetSum() { super(); } public GetSum(int num) { super(); this.num = num; } public Integer call() throws Exception { int sum=0; for(int i=1;i<=num;i++){ sum+=i; } return sum; }
public static void main(String[] args) throws InterruptedException, ExecutionException { //異步計算1-n的和 //兩條線程分別計算1-100和1-200的和 //獲取線程池對象
        ExecutorService es=Executors.newFixedThreadPool(2); //創建線程任務對象 構造方法有返回值
        GetSum r1=new GetSum(100); GetSum r2=new GetSum(200); //將線程任務提交給線程池執行
        Future<Integer> f1=es.submit(r1); Future<Integer> f2=es.submit(r2); //獲取返回值 任務同時進行,但結果有先后
 System.out.println(f1.get()); System.out.println(f2.get()); //銷毀線程池
 es.shutdown(); }
  //5050 20100

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM