溫故知新----執行緒之Runnable與Callable介面的本質區別

2023-03-27 18:00:48

溫故知新----執行緒之Runnable與Callable介面的本質區別

預備知識:Java中的執行緒物件是Thread,新建執行緒也只有通過建立Thread物件的範例來建立。

先說結論

1 Runnable沒有返回值的FunctionalInterface(jdk 1.8概念)介面,相反Callable是有返回值的FunctionalInterface介面

2 Runnable + Thread 建立一個無返回結果的任務執行緒

3 Runnable + Callable +Thread 建立一個有返回結果的任務執行緒

一:Runnable 範例

​ 建立一個無返回結果的任務執行緒,so eazy !!!!

public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "我是一個無返回結果的任務執行緒");
            }
        },"執行緒一:").start(); //start()開啟任務
    }

二:Callable範例

2.1 JAVA非同步程式設計之Callbacks與Futures模型 我是用Executors執行緒池的方式來建立的。

2.2 用最原始的方法

public class PrimitiveCallable implements Callable, Runnable {
    
    public static void main(String[] args) {
        //實現
        new Thread(new PrimitiveCallable(), "執行緒二:").start();
    }
    @Override
    public void run() {//Runnable實現
        try {
            Object call = this.call();
            System.out.println(call);
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }
    @Override
    public Object call() throws Exception { //Callable 實現
        return "非同步任務返回的結果!!!";
    }
}

2.3 FutureTask 一種jdk的實現方式

public class FutureTask<V> implements RunnableFuture<V> { //RunnableFuture 實現了以上2個介面
    ........省略.........
	public void run() { //重寫run實現
        if (state != NEW ||
            !UNSAFE.compareAndSwapObject(this, runnerOffset,
                                         null, Thread.currentThread()))
            return;
        try {
            Callable<V> c = callable; //構建物件是傳入的引數
            if (c != null && state == NEW) {
                V result;
                boolean ran;
                try {
                    result = c.call(); //呼叫任務並返回結果
                    ran = true;
                } catch (Throwable ex) {
                    result = null;
                    ran = false;
                    setException(ex); //設定異常時的結果
                }
                if (ran)
                    set(result); //設定結果
            }
        } finally {
            runner = null;
            int s = state;
            if (s >= INTERRUPTING)
                handlePossibleCancellationInterrupt(s);
        }
    }
     ........省略.........
}

小結

1 不要糾結有幾種建立執行緒的方法了,就一種即通過Thread,但Thread有9個建構函式方法

2 9個建構函式方法

1 public Thread()
2 public Thread(Runnable target)
3 Thread(Runnable target, AccessControlContext acc)
4 public Thread(ThreadGroup group, Runnable target)
5 public Thread(String name)
6 public Thread(ThreadGroup group, String name)
7 public Thread(Runnable target, String name)
8 public Thread(ThreadGroup group, Runnable target, String name)
9 public Thread(ThreadGroup group, Runnable target, String name,
                  long stackSize)