📅  最后修改于: 2023-12-03 15:31:57.046000             🧑  作者: Mango
在Java多线程编程中,我们可能需要在一个线程中进行一些异步操作,这时候我们就需要使用Future和FutureTask。
首先来介绍一下Future。Future表示异步计算的结果,它提供了一些方法来检查计算是否完成以及获取计算结果。
public class FutureExample {
public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(5);
Future<Integer> future = executor.submit(() -> {
Thread.sleep(1000);
return 123;
});
while (!future.isDone()) {
System.out.println("Calculating...");
Thread.sleep(300);
}
System.out.println("Result: " + future.get());
executor.shutdown();
}
}
在这个例子中,我们使用ExecutorService
创建了线程池,并使用submit
提交了一个任务。这个任务会睡眠1秒,然后返回整数123。我们在主线程中调用future.isDone()
来检查计算是否完成,如果还没有完成,就输出"Calculating..."并睡眠300毫秒。当计算完成后,我们就可以通过future.get()
获取计算结果。
FutureTask实现了Future接口,同时它也是Runnable的子类,因此它既可以作为一个异步任务的返回结果使用,也可以在Executor中执行。和Future不同的是,FutureTask可以通过构造函数或者set方法设置计算结果,因此可以用于那些预先知道结果的计算,可以减少不必要的线程等待时间。
我们可以使用以下构造函数来创建FutureTask:
FutureTask继承了重载的get()方法,可以通过get()方法同步等待任务完成并返回执行结果,也可以通过get(long timeout, TimeUnit unit)方法来指定等待任务的最长时间。
public class FutureTaskExample {
public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(5);
FutureTask<Integer> futureTask = new FutureTask<>(() -> {
Thread.sleep(1000);
return 123;
});
executor.submit(futureTask);
while (!futureTask.isDone()) {
System.out.println("Calculating...");
Thread.sleep(300);
}
System.out.println("Result: " + futureTask.get());
executor.shutdown();
}
}
在这个例子中,我们使用ExecutorService创建了线程池,然后创建了一个FutureTask。其中,我们传入一个Callable对象来实现异步计算。我们使用submit()
方法将FutureTask提交给线程池,最终在主线程中调用futureTask.get()
获取计算结果。
在多线程编程中,当我们需要进行异步计算、并发编程的时候,Future和FutureTask是非常有用的工具。我们可以使用它们来检查任务是否完成,获取计算结果,甚至可以指定等待的最长时间。同时,FutureTask还具有Runnable的特性,可以在线程中执行计算任务,非常灵活和实用。