Java多線程編程——線程建立方式

來源:互聯網
上載者:User

在Java中,建立線程有以下幾種方式:

通過實現 Runnable 介面;

通過繼承 Thread 類本身;

通過 Callable 和 Future 建立線程。

通過實現 Runnable 介面來建立線程

建立線程最簡單的方式就是直接實現Runnable介面,該介面定義了一個run()方法,在我們的實作類別中通過對該方法的實現來定義我們自己的任務,這樣使得我們在建立並啟動線程之後能夠執行我們自己的任務。比如我們要執行一個倒計時的任務,我們就可以像下面的代碼一樣實現:

public class RunnableDemo implements Runnable {    @Override    public void run() {        System.out.println("倒計時開始:");        for(int i = 0; i < 10 ; i++){            System.out.println(10-i);            try {                Thread.sleep(1000);            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }    public static void main(String[] args) {        Thread thread = new Thread(new RunnableDemo(),"Runnable-Thread");        thread.start();    }}

通過繼承Thread來建立線程

建立一個線程的第二種方法是建立一個新的類,該類繼承 Thread 類(關於Thread類我們會在後續的文章中詳細闡述),然後建立一個該類的執行個體。
繼承類必須重寫 run() 方法,該方法是新線程的進入點。它也必須調用 start() 方法才能執行。
該方法儘管被列為一種多線程實現方式,但是本質上也是實現了 Runnable 介面的一個執行個體。
通過繼承Thread重寫上面的倒計時任務如下:

public class ThreadDemo extends Thread {    public void run() {        System.out.println("倒計時開始:");        for(int i = 0; i < 10 ; i++){            System.out.println(10-i);            try {                Thread.sleep(1000);            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }    public static void main(String[] args) {        ThreadDemo thread = new ThreadDemo();        thread.start();    }}

通過 Callable 和 Future 建立線程

Runnable是執行工作的獨立任務,但是他不返回任何值,如果你希望任務在完成時能夠返回一個值,那麼可以實現Callable介面來實現。Callable介面是一種具有型別參數的泛型介面,通過查看它的源碼我們可以發現,它的型別參數所表示的是從call()中返回的值的類型。Callable類型的任務可以有兩種執行方式:

藉助FutureTask執行

藉助Executor來運執行

藉助FutureTask執行

建立 Callable 介面的實作類別,並實現 call() 方法,該 call() 方法將作為線程執行體,並且有傳回值。

建立 Callable 實作類別的執行個體,使用 FutureTask 類來封裝 Callable 對象,該 FutureTask 對象封裝了該 Callable 對象的 call() 方法的傳回值。

使用 FutureTask 對象作為 Thread 對象的 target 建立並啟動新線程。

調用 FutureTask 對象的 get() 方法來獲得子線程執行結束後的傳回值。

public class CallableThreadDemo implements Callable<Integer> {    @Override    public Integer call() throws Exception {        System.out.println("線程在進行計算");        Thread.sleep(1000);        int sum = 0;        for(int i=0;i<100;i++)            sum += i;        return sum;    }    public static void main(String[] args) throws InterruptedException, ExecutionException {        Callable<Integer> mycallabletask = new CallableThreadDemo();          FutureTask<Integer> futuretask= new FutureTask<Integer>(mycallabletask);          new Thread(futuretask).start();        System.out.println("傳回值:"+futuretask.get());    }}

藉助Executor來運執行

藉助Executor必須使用ExecutorService.submit()方法調用它,下面是對上一個執行個體的改造:

public class CallableThreadDemo2 implements Callable<Integer> {    @Override    public Integer call() throws Exception {        System.out.println("線程在進行計算");        Thread.sleep(1000);        int sum = 0;        for(int i=0;i<100;i++)            sum += i;        return sum;    }    public static void main(String[] args) throws InterruptedException, ExecutionException {        ExecutorService exec = Executors.newCachedThreadPool();        Future<Integer> future = exec.submit(new CallableThreadDemo2());        System.out.println("傳回值:"+ future.get());        exec.shutdown();    }}

三種方式對比

採用實現 Runnable、Callable 介面的方式建立多線程時,線程類只是實現了 Runnable 介面或 Callable 介面,還可以繼承其他類。

使用繼承 Thread 類的方式建立多線程時,編寫簡單,如果需要訪問當前線程,則無需使用 Thread.currentThread() 方法,直接使用 this 即可獲得當前線程。

參考:
http://www.runoob.com/java/java-multithreading.html
《java編程思想》

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.