Как FutureTask является асинхронным вычислением

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

Если я сделаю это в основном, он создаст новый поток и отправит ему задачу для асинхронного расчета.

Если вы видите документацию FutureTask, там также написано:

Отменяемые асинхронные вычисления. Этот класс предоставляет базовую реализацию Future с методами для запуска и отмены вычислений, запроса, чтобы увидеть, завершено ли вычисление, и получения результата вычисления.

Так как FutureTask является asynchronous computation создает ли он поток внутри себя и отправляет задачу, которую мы ему даем во время создания экземпляра FutureTask лайк:

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
        }
    }

1 ответ

Решение

Так как FutureTask является асинхронным вычислением, он создает поток внутри себя и передает задачу, которую мы даем ему во время создания экземпляра FutureTask, например:

FutureTask не предназначен для непосредственного использования пользователем. Он предназначен для использования через ExecutorService интерфейс и классы, которые его реализуют. Это те классы, которые используют FutureTask и разветвить темы, и т. д. Возможно, вам придется прочитать больше информации о том, как использовать ExecutorService классы параллелизма.

ThreadPoolExecutor Класс является основным, который фактически управляет потоками в пуле. Как правило, вы звоните Executors.newCachedThreadPool() или же Executors.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 видит, нужно ли ему добавить больше потоков в пул. отправляет его в очередь задач, которая может либо отклонить его, либо принять его, а затем потоки исключают задачу из очереди и запускают их в фоновом режиме.

Другие вопросы по тегам