Callble インターフェイスがマルチスレッドを作成する [詳細な概要]

Callble インターフェイスの紹介

Callable はスレッドを作成するときに使用されるインターフェイスで、Runnable に似ています。Runnable は複数のスレッドを作成するときに戻り値がありませんが、Callable は戻り値を持ちます。通常、戻り値を伴うマルチスレッドが必要な場合は Callable を使用します。

呼び出し可能と実行可能の違い

  • 違う名前
  • 書き換え方法が異なり、call() メソッドは Callable に、run() メソッドは Runnable にあります。
  • ジェネリックスの有無。Callable インターフェイスにはジェネリックスがありますが、Runnable インターフェイスにはジェネリックスがありません。
  • 戻り値の有無 (Callable インターフェースには戻り値があり、戻り値の型がジェネリック型と一致するかどうか)
  • 構築方法は異なりますが、Callable インターフェースは、Runnable インターフェースに接続するための媒体として FutureTask クラスを使用します。

将来のインターフェース

call() メソッドが完了したら、メインスレッドがそのスレッドによってどのような結果が返されたかをメインスレッドが認識できるように、結果をメインスレッドが認識しているオブジェクトに格納する必要があります。これを行うには、Future オブジェクトを使用できます。

Future は結果を保持するオブジェクトと考えてください。しばらくの間は結果を保持しないかもしれませんが、将来 (Callable が返されたら) 保持されるようになります。Future は基本的に、メインスレッドが進行状況と他のスレッドの結果を追跡できる方法です。このインターフェイスを実装するには、5 つのメソッドを書き直す必要があります。重要なメソッドは次のとおりです。

public boolean cancel(boolean mayInterrupt)//:用于停止任务。

タスクがまだ開始されていない場合は、タスクが停止されます。開始された場合、タスクは、mayInterrupt が true の場合にのみ中断されます。

`public Object get()//抛出 InterruptedException,ExecutionException:用于获取任务的结果`。

タスクが完了した場合は、すぐに結果を返します。それ以外の場合は、タスクが完了するのを待ってから結果を返します。

public boolean isDone()://如果任务完成,则返回 true,否则返回 false

Callable と Future は 2 つのことを行うことがわかります。Callable は、別のスレッドで実行されるタスクをカプセル化するという点で Runnable に似ており、Future は別のスレッドから取得した結果を保存するために使用されます。実際、Future は Runnables でも​​使用できます。スレッドを作成するには、Runnable が必要です。結果を出すためには未来が必要です。

FutureTask クラス

FutureTask クラスは RunnableFuture インターフェイスを実装し、RunnnableFuture インターフェイスは Runnable インターフェイスと Future インターフェイスを継承するため、FutureTask は非同期計算の結果を提供するタスクです。
FutureTask を使用して、Callable オブジェクトまたは Runnbale オブジェクトをラップできます。FutureTask は Runnable インターフェイスを実装しているため、FutureTask を Executor に送信することもできます


FutureTask コンストラクター内のソース コードを見てみましょう。

// 创建一个FutureTask,一旦运行就执行给定的Callable
public FutureTask(Callable<V> callable) {
    
    
    if (callable == null)
        throw new NullPointerException();
    this.callable = callable;
    this.state = NEW;       // ensure visibility of callable
}
// 创建一个FutureTask,一旦运行就执行给定的Ru你那边了,并安排成功完成时get返回给定的结果
public FutureTask(Runnable runnable, V result) {
    
    
    this.callable = Executors.callable(runnable, result);
    this.state = NEW;       // ensure visibility of callable
}

その他の一般的に使用されるコード:

// get()获取结果
public V get() throws InterruptedException, ExecutionException {
    
    
    int s = state;
    if (s <= COMPLETING)
        s = awaitDone(false, 0L);
    return report(s);
}
// outcome就是返回值
private V report(int s) throws ExecutionException {
    
    
    Object x = outcome;
    if (s == NORMAL)
        return (V)x;
    if (s >= CANCELLED)
        throw new CancellationException();
    throw new ExecutionException((Throwable)x);
}

呼び出し可能インターフェイスはマルチスレッドを作成します

FutureTaskによる実行

public class CallableTest {
    
    
    public static void main(String[] args) throws ExecutionException, InterruptedException {
    
    
        new Thread(()->{
    
    
            System.out.println(Thread.currentThread().getName()+"执行Runnable");
        }).start();
        FutureTask<String> task = new FutureTask<>(() -> {
    
    
            System.out.println(Thread.currentThread().getName() + "使用Callable接口");
            return "Callable接口返回值";
        });
        new Thread(task).start();
        System.out.println("Callable返回值:" + task.get());
    }
}


出力は次のとおりです。

Thread-0执行Runnable
Thread-1使用Callable接口
Callable返回值:Callable接口返回值

要約(強調)

1. 時間のかかる操作をメイン スレッドで実行する必要があるが、メイン スレッドをブロックしたくない場合は、これらのジョブを Future オブジェクトに渡してバックグラウンドで完了させることができます。 future では、Future オブジェクトを使用して、バックグラウンド ジョブの情報 (計算結果や実行ステータス) を取得できます。
2. 一般に、FutureTask は時間のかかる計算に主に使用され、メインスレッドは独自のタスクを完了した後に結果を取得できます。
3. 結果は計算が完了した場合にのみ取得できます。計算が完了していない場合、get メソッドはブロックされます。計算が完了すると、再開したりキャンセルしたりすることはできません。get メソッドを使用すると、計算が完了した場合にのみ結果を取得できます。それ以外の場合は、タスクが完了状態になるまでブロックされ、その後結果が返されるか、例外がスローされます。
4. 計算は 1 回のみです。

おすすめ

転載: blog.csdn.net/weixin_54046648/article/details/128183268