検索
ホームページJava&#&チュートリアルJava マルチスレッドでの Callable と Future の詳細な紹介 (コード例)

この記事では、Java マルチスレッドにおける Callable と Future についての詳細な紹介 (コード例) を紹介します。必要な方は参考にしていただければ幸いです。

Callable と Future が登場する理由

スレッドを作成するには 2 つの方法があります。1 つは Thread を直接継承する方法、もう 1 つは Runnable インターフェースを実装する方法です。 。
これら 2 つの方法には欠点があります。タスクの完了後に実行結果を取得できないということです。
実行結果を取得する必要がある場合は、共有変数またはスレッド通信を通じて結果を取得する必要があり、使用するのがより面倒です。
Java 1.5からは、タスクの実行完了後にタスクの実行結果を取得できるCallableとFutureが提供されています。

Callable と Future の概要

Callable インターフェイスは、呼び出して結果を返すことができるコードの一部を表し、Future インターフェイスは非同期タスクを表します。まだ終わっていない仕事がもたらす未来。したがって、Callable は結果の生成に使用され、Future は結果の取得に使用されます。
Callable インターフェイスはジェネリックスを使用して戻り値の型を定義します。 Executors クラスは、スレッド プール内の Callable 内でタスクを実行するための便利なメソッドをいくつか提供します。 Callable タスクは並列であるため (並列とは、全体が並列に見えることを意味します。実際には、特定の時点で 1 つのスレッドだけが実行されます)、返される結果を待つ必要があります。
java.util.concurrent.Future オブジェクトは、この問題を解決します。スレッド プールが Callable タスクを送信すると、Future オブジェクトが返され、これを使用して Callable タスクのステータスを確認し、Callable によって返された実行結果を取得できます。 Future は、Callable が終了するのを待ってその実行結果を取得できるように get() メソッドを提供します。

呼び出し可能および実行可能

java.lang.Runnable、これはインターフェイスであり、その中で宣言されている run() メソッドは 1 つだけです:

public interface Runnable {
    public abstract void run();
}

run()メソッドの戻り値はvoid型のため、タスク実行後に結果は返されません。

Callable は java.util.concurrent パッケージの下にあり、これもインターフェイスであり、その中で宣言されているメソッドは 1 つだけですが、このメソッドは call() と呼ばれます:

public interface Callable<v> {
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    V call() throws Exception;
}</v>

Thisジェネリック インターフェイスの場合、call() 関数によって返される型は、渡された V 型です。

Callable の使用

通常、これは ExecutorService と組み合わせて使用​​され、submit メソッドのいくつかのオーバーロードされたバージョンが ExecutorService インターフェイスで宣言されます。

<t> Future<t> submit(Callable<t> task);
<t> Future<t> submit(Runnable task, T result);
Future> submit(Runnable task);</t></t></t></t></t>

最初の submit メソッドのパラメーターの型は Callable です。

現時点では、Callable は一般的に ExecutorService と組み合わせて使用​​されることだけを知っておいてください。具体的な使用方法については後述します。

通常、最初の送信メソッドと 3 番目の送信メソッドが使用され、2 番目の送信メソッドはほとんど使用されません。

Future

Future は、特定の Runnable または Callable タスクの実行結果をキャンセルし、完了したかどうかをクエリし、結果を取得することです。必要に応じて、タスクが結果を返すまでブロックされる get メソッドを通じて実行結果を取得できます。

Future クラスは java.util.concurrent パッケージの下にあります。これは、Future インターフェースで 5 つのメソッドを宣言します。

    cancel メソッドはタスクのキャンセルに使用され、タスクのキャンセルが成功した場合は true を返し、タスクのキャンセルが失敗した場合は false を返します。 MayInterruptIfRunning パラメータは、実行中だが完了していないタスクをキャンセルできるかどうかを示します。 true に設定すると、実行中のタスクをキャンセルできることを意味します。タスクが完了した場合、mayInterruptIfRunning が true か false に関係なく、このメソッドは必ず false を返します。つまり、完了したタスクがキャンセルされた場合、タスクが実行中であり、mayInterruptIfRunning が true に設定されている場合は false を返します。 MayInterruptIfRunning が false に設定されている場合は true を返し、タスクが実行されていない場合は false を返します。mayInterruptIfRunning が true であっても false であっても、必ず true を返します。
  • isCancelled メソッドは、タスクが正常にキャンセルされたかどうかを示します。タスクが正常に完了する前にキャンセルされた場合は、true を返します。
  • isDone メソッドは、タスクが完了したかどうかを示します。タスクが完了した場合は、
  • #get() メソッドが使用されます。実行結果を取得するには、このメソッドはブロックされ、タスクの実行が完了するまで待機してから戻ります。指定時間内に取得できなかった場合は、結果に達した時点で直接nullを返します。
  • Future は、タスクが完了したかどうかを判断する
  • という 3 つの関数を提供します。タスクを中断できる;
タスクの実行結果を取得できる。
  1. Future は単なるインターフェイスであるため、オブジェクトの作成に直接使用することはできません。そのため、次の FutureTask があります。

    FutureTask
  2. FutureTask は RunnableFuture インターフェイスを実装します。このインターフェイスの定義は次のとおりです。

  3. public interface Future<v> {
        boolean cancel(boolean mayInterruptIfRunning);
        boolean isCancelled();
        boolean isDone();
        V get() throws InterruptedException, ExecutionException;
        V get(long timeout, TimeUnit unit)
            throws InterruptedException, ExecutionException, TimeoutException;
    }</v>
  4. このインターフェイスが Runnable を実装していることがわかります。 Future インターフェイス。インターフェイス内の特定の実装は FutureTask によって実装されます。このクラスの 2 つの構築メソッドは次のとおりです。

    public FutureTask(Callable<v> callable) {  
            if (callable == null)  
                throw new NullPointerException();  
            sync = new Sync(callable);  
        }  
        public FutureTask(Runnable runnable, V result) {  
            sync = new Sync(Executors.callable(runnable, result));  
        }</v>

    如上提供了两个构造函数,一个以Callable为参数,另外一个以Runnable为参数。这些类之间的关联对于任务建模的办法非常灵活,允许你基于FutureTask的Runnable特性(因为它实现了Runnable接口),把任务写成Callable,然后封装进一个由执行者调度并在必要时可以取消的FutureTask。

    FutureTask可以由执行者调度,这一点很关键。它对外提供的方法基本上就是Future和Runnable接口的组合:get()、cancel、isDone()、isCancelled()和run(),而run()方法通常都是由执行者调用,我们基本上不需要直接调用它。

    FutureTask的例子
    public class MyCallable implements Callable<string> {  
        private long waitTime;   
        public MyCallable(int timeInMillis){   
            this.waitTime=timeInMillis;  
        }  
        @Override  
        public String call() throws Exception {  
            Thread.sleep(waitTime);  
            //return the thread name executing this callable task  
            return Thread.currentThread().getName();  
        }  
    
    }</string>
    public class FutureTaskExample {  
         public static void main(String[] args) {  
            MyCallable callable1 = new MyCallable(1000);                       // 要执行的任务  
            MyCallable callable2 = new MyCallable(2000);  
    
            FutureTask<string> futureTask1 = new FutureTask<string>(callable1);// 将Callable写的任务封装到一个由执行者调度的FutureTask对象  
            FutureTask<string> futureTask2 = new FutureTask<string>(callable2);  
    
            ExecutorService executor = Executors.newFixedThreadPool(2);        // 创建线程池并返回ExecutorService实例  
            executor.execute(futureTask1);  // 执行任务  
            executor.execute(futureTask2);    
    
            while (true) {  
                try {  
                    if(futureTask1.isDone() && futureTask2.isDone()){//  两个任务都完成  
                        System.out.println("Done");  
                        executor.shutdown();                          // 关闭线程池和服务   
                        return;  
                    }  
    
                    if(!futureTask1.isDone()){ // 任务1没有完成,会等待,直到任务完成  
                        System.out.println("FutureTask1 output="+futureTask1.get());  
                    }  
    
                    System.out.println("Waiting for FutureTask2 to complete");  
                    String s = futureTask2.get(200L, TimeUnit.MILLISECONDS);  
                    if(s !=null){  
                        System.out.println("FutureTask2 output="+s);  
                    }  
                } catch (InterruptedException | ExecutionException e) {  
                    e.printStackTrace();  
                }catch(TimeoutException e){  
                    //do nothing  
                }  
            }  
        }  
    }</string></string></string></string>

以上がJava マルチスレッドでの Callable と Future の詳細な紹介 (コード例)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事はsegmentfaultで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
高度なJavaプロジェクト管理、自動化の構築、依存関係の解像度にMavenまたはGradleを使用するにはどうすればよいですか?高度なJavaプロジェクト管理、自動化の構築、依存関係の解像度にMavenまたはGradleを使用するにはどうすればよいですか?Mar 17, 2025 pm 05:46 PM

この記事では、Javaプロジェクト管理、自動化の構築、依存関係の解像度にMavenとGradleを使用して、アプローチと最適化戦略を比較して説明します。

適切なバージョン化と依存関係管理を備えたカスタムJavaライブラリ(JARファイル)を作成および使用するにはどうすればよいですか?適切なバージョン化と依存関係管理を備えたカスタムJavaライブラリ(JARファイル)を作成および使用するにはどうすればよいですか?Mar 17, 2025 pm 05:45 PM

この記事では、MavenやGradleなどのツールを使用して、適切なバージョン化と依存関係管理を使用して、カスタムJavaライブラリ(JARファイル)の作成と使用について説明します。

カフェインやグアバキャッシュなどのライブラリを使用して、Javaアプリケーションにマルチレベルキャッシュを実装するにはどうすればよいですか?カフェインやグアバキャッシュなどのライブラリを使用して、Javaアプリケーションにマルチレベルキャッシュを実装するにはどうすればよいですか?Mar 17, 2025 pm 05:44 PM

この記事では、カフェインとグアバキャッシュを使用してJavaでマルチレベルキャッシュを実装してアプリケーションのパフォーマンスを向上させています。セットアップ、統合、パフォーマンスの利点をカバーし、構成と立ち退きポリシー管理Best Pra

キャッシュや怠zyなロードなどの高度な機能を備えたオブジェクトリレーショナルマッピングにJPA(Java Persistence API)を使用するにはどうすればよいですか?キャッシュや怠zyなロードなどの高度な機能を備えたオブジェクトリレーショナルマッピングにJPA(Java Persistence API)を使用するにはどうすればよいですか?Mar 17, 2025 pm 05:43 PM

この記事では、キャッシュや怠zyなロードなどの高度な機能を備えたオブジェクトリレーショナルマッピングにJPAを使用することについて説明します。潜在的な落とし穴を強調しながら、パフォーマンスを最適化するためのセットアップ、エンティティマッピング、およびベストプラクティスをカバーしています。[159文字]

Javaのクラスロードメカニズムは、さまざまなクラスローダーやその委任モデルを含むどのように機能しますか?Javaのクラスロードメカニズムは、さまざまなクラスローダーやその委任モデルを含むどのように機能しますか?Mar 17, 2025 pm 05:35 PM

Javaのクラスロードには、ブートストラップ、拡張機能、およびアプリケーションクラスローダーを備えた階層システムを使用して、クラスの読み込み、リンク、および初期化が含まれます。親の委任モデルは、コアクラスが最初にロードされ、カスタムクラスのLOAに影響を与えることを保証します

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

SecLists

SecLists

SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。

VSCode Windows 64 ビットのダウンロード

VSCode Windows 64 ビットのダウンロード

Microsoft によって発売された無料で強力な IDE エディター