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