JUC併發程式設計學習筆記(六)Callable(簡單)

高同學,你好發表於2023-11-03

Callable(簡單)

callable介面和runnable介面類似,都是為了執行另外一條執行緒而設計的,區別是Runnable不會返回結果也不會丟擲異常。

1、可以有返回值

2、可以丟擲異常

3、方法不同;run()/call();

Runnable

實現Runnable介面,重寫run方法,無返回值

//原執行緒
class RunnableThread implements Runnable{
    @Override
    public void run() {

    }
}

Callable

實現Callable介面,重寫call方法,有返回值,可在實現介面時設定

//callable執行緒
class CallableThread implements Callable<String>{

    @Override
    public String call() throws Exception {
        return null;
    }
}

Callable中泛型的引數等於方法的返回型別

啟動callable

Thread類中沒有填入callable介面的過載方法,所以我們需要透過適配類完成操作

透過查詢Runnable介面的實現類,能夠發現有一個FutureTask中提供了Callable引數的構造方法

所以,可以透過FutureTask來作為一箇中間人的角色使用執行緒執行callable的實現類。

具體程式碼

package org.example.callable;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class CallableTest {
    public static void main(String[] args) {
//        new Thread(()->{new Runnable()}).start();
//        new Thread(()->{new FutureTask<V>()}).start();
//        new Thread(()->{new FutureTask<V>( Callable )}).start();
        CallableThread thread = new CallableThread();//怎樣啟動Callable

        FutureTask task = new FutureTask(thread);//適配類
        new Thread(task,"A").start();//正常列印兩個call,但是這邊只會列印一個,結果會被快取,提高效率
        new Thread(task,"B").start();
        try {
            String  o = (String) task.get();//get方法可能產生阻塞,耗時操作時;透過非同步操作或者將它放在最後使用
            System.out.println(o);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }

    }
}

//callable執行緒
class CallableThread implements Callable<String>{

    @Override
    public String call() throws Exception {
        System.out.println("call");
        return "cals";
    }
}

細節

1、為了提高效率所以有快取

2、耗時操作時,獲取callable的返回值可能會產生對該方法呼叫例項的執行緒阻塞

相關文章