8
new Thread(new Runnable() {
           public void run() {
                 .............
                 .............
                 .............
    }
}).start();

メインでこれを行うと、新しいスレッドが作成され、非同期計算のためにタスクが送信されます。

FutureTask のドキュメントを見ると、次のようにも書かれています。

キャンセル可能な非同期計算。このクラスは、Future の基本実装を提供し、計算を開始およびキャンセルするメソッド、計算が完了したかどうかを照会するメソッド、および計算の結果を取得するメソッドを備えています。

では、内部でスレッドを作成し、インスタンス化時に指定したタスクを次のようにサブミットする方法FutureTaskは次のとおりです。asynchronous computationFutureTask

FutureTask f = new FutureTask(new MyCallable());

それ以外の場合は非同期計算にすることはできません。非同期計算にするために、タスクをスレッドに送信するFutureTask ソース コードのコード スニペットを提供してください。ありがとう。


答えがわかりました。基本的に、呼び出し元と同じスレッドでタスクを実行しようとしています。与えられたコードでそれはかなり明白です:

あなたがfutureTask.run()それを呼び出すsync.innerRun();sync、内部クラスのインスタンスが呼び出されますSync。つまりcall()、同じスレッドで呼び出し可能なオブジェクトを呼び出すだけです。

void innerRun() {
        if (!compareAndSetState(READY, RUNNING))
            return;

        runner = Thread.currentThread(); //here it is getting the current thread
        if (getState() == RUNNING) { 
            V result;
            try {
                result = callable.call();//here calling call which executes in the caller thread.
            } catch (Throwable ex) {
                setException(ex);
                return;
            }
            set(result);
        } else {
            releaseShared(0); // cancel
        }
    }
4

1 に答える 1

8

したがって、FutureTask が非同期計算である方法は、内部でスレッドを作成し、FutureTask のインスタンス化時に指定したタスクを次のように送信します。

FutureTaskユーザーが直接使用するようには設計されていません。ExecutorServiceインターフェイスとそれを実装するクラスを介して使用するように設計されています。スレッドなどを使用およびフォークするのはこれらのクラスです。同時実行クラスの使用方法FutureTaskについては、詳細を読む必要がある場合があります。ExecutorService

このThreadPoolExecutorクラスは、プール内のスレッドの管理を実際に行う主要なクラスです。通常、Executors.newCachedThreadPool()orExecutors.newFixedThreadPool(10)を呼び出してそのインスタンスを取得します。

// create a thread pool with 10 workers
ExecutorService threadPool = Executors.newFixedThreadPool(10);
// define your jobs somehow
for (MyCallable job : jobsToDo) {
    // under the covers this creates a FutureTask instance
    Future future = threadPool.submit(job);
    // save the future if necessary in a collection or something
}
// once we have submitted all jobs to the thread pool, it should be shutdown
threadPool.shutdown();
// now we can go back and call `future.get()` to get the results from our jobs

学術的な観点からは、カバーの下で TPE が拡張され、スレッドプール内のタスクを管理するために使用されているクラスAbstractExecutorServiceを確認できます。FutureTask

public <T> Future<T> submit(Callable<T> task) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<T> ftask = newTaskFor(task);
    execute(ftask);
    return ftask;
}
...
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
    return new FutureTask<T>(callable);
}

TPE 内のコードは非常に複雑で、非同期呼び出しを実行する "スニペット" を示すのは簡単ではありません。TPE は、プールにさらにスレッドを追加する必要があるかどうかを確認します。タスク キューはそれを拒否または受け入れることができます。その後、スレッドはタスクをデキューし、バックグラウンドで実行します。

于 2013-11-04T13:20:45.957 に答える