併發編程(壹):建立線程的三種方式及其對比

建立線程的三種方式及其對比


1. 繼承 Thread類

(1). 繼承Thread類。並重寫run()方法,該方法無參數,無返回值;java

(2). 建立子類實例,並實例化對象;編程

(3). 經過start()方法啓動,注意:不是經過run()方法啓動。多線程

public class ThreadDemo extends Thread{
    public void run(){
        System.out.println("繼承Thread建立線程的.");
    }
}

public class ThreadAction {
    public static void main(String[] args) {
        Thread threadDemo=new ThreadDemo();
        threadDemo.start();
    }
}

2. 實現Runnable接口

(1). 實現Runnable接口,並從新run()方法;ide

(2). 建立Runnable實現類的實例,並用這個實例做爲Thread的target建立線程對象;this

(3). 經過start()啓動線程。線程

public class RunnableDemo implements Runnable{

    @Override
    public void run() {
        System.out.println("實現Runnable建立線程的.");
    }
}

public class ThreadAction {
    public static void main(String[] args) {
        RunnableDemo runnableDemo = new RunnableDemo();
        Thread thread = new Thread(runnableDemo);
        thread.start();
    }
}

3. 經過Callable和Future建立線程

產生背景:這種建立線程的方式在jdk1.5後出現,目的是彌補上面兩種建立線程方式,其中的run()方法不能有返回值,不能拋出異常等問題。code

(1). 建立實現Callable的實現類,並實現call()方法;對象

(2). 建立該實現類的實例(從java8開始能夠直接使用Lambda表達式建立Callable對象);繼承

(3). 使用FutureTask類來包裝Callable對象,該FutureTask對象封裝了Callable對象的call()方法的返回值;接口

(4). 使用FutureTask對象做爲Thread對象的target建立並啓動線程(由於FutureTask實現了Runnable接口);

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

public class CallableDemo implements Callable<String> {
    
    @Override
    public String call() throws Exception {
        return "hello ,我是經過實現Callable接口的方式建立線程。";
    }
}

public class ThreadAction {
    public static void main(String[] args) {
        CallableDemo callableDemo = new CallableDemo();
        // 使用FutureTask類來包裝Callable對象
        FutureTask<String> stringFutureTask = new FutureTask<>(callableDemo);
        Thread thread = new Thread(stringFutureTask);
        thread.start();
        try {
            System.out.println(stringFutureTask.get());
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }
}

4. 建立線程的三種方式的對比

實現Runnable、Callable接口的方式建立多線程

  • 優點:該線程只是實現了接口,還能夠繼承其餘類.在這種方式下多個線程共享一個target對象,因此很是適合多個相同線程來處理同一份資源的狀況,從而能夠將CPU、代碼和數據分開,造成清晰的模型,較好地體現了面向對象的思想.
  • 劣勢:編程稍微複雜,若是要訪問當前線程,則必須使用Thread.currentThread()方法。

繼承Thread類

  • 優點:代碼編寫簡單,當前Thread可用this獲取.
  • 劣勢:繼承Thread類,不可繼承其餘類.
相關文章
相關標籤/搜索