Java中的Future和FutureTask
先决条件:未来和可调用
未来:
Future接口提供了检查计算是否完成、等待其完成和检索计算结果的方法。计算完成后,使用 Future 的 get() 方法检索结果,并阻塞直到完成。
Future 和 FutureTask 都在Java 1.5 的Java .util.concurrent 包中可用。
未来任务:
- FutureTask 实现Future 接口和RunnableFuture 接口,意思是可以将FutureTask 用作Runnable 并提交给ExecutorService 执行。
- 当调用 Future.submit() Callable 或 Runnable 对象时,大部分时间 ExecutorService 创建 FutureTask,也可以手动创建它。
- FutureTask 就像一个闩锁。
- FutureTask 表示的计算是用 Callable 接口实现的。
- 它实现了 Future 或 Callable 接口。
- get() 方法的行为取决于任务的状态。如果任务没有完成,get() 方法会等待或阻塞,直到任务完成。任务完成后,它会返回结果或抛出 ExecutionException。
使用 Future 的一个例子是使用线程池。当向 ExecutorService 提交一个运行时间较长的任务时,它会立即返回一个 Future 对象。此 Future 对象可用于完成任务并获取计算结果。
示例:创建两个任务。一个任务完全执行后,等待2000毫秒后,第二个任务正在执行
注意:在线 IDE 在 sleep() 方法上无法正常工作。
Java
// Java program do two FutureTask
// using Runnable Interface
import java.util.concurrent.*;
import java.util.logging.Level;
import java.util.logging.Logger;
class MyRunnable implements Runnable {
private final long waitTime;
public MyRunnable(int timeInMillis)
{
this.waitTime = timeInMillis;
}
@Override
public void run()
{
try {
// sleep for user given millisecond
// before checking again
Thread.sleep(waitTime);
// return current thread name
System.out.println(Thread
.currentThread()
.getName());
}
catch (InterruptedException ex) {
Logger
.getLogger(MyRunnable.class.getName())
.log(Level.SEVERE, null, ex);
}
}
}
// Class FutureTaskExample execute two future task
class FutureTaskExample {
public static void main(String[] args)
{
// create two object of MyRunnable class
// for FutureTask and sleep 1000, 2000
// millisecond before checking again
MyRunnable myrunnableobject1 = new MyRunnable(1000);
MyRunnable myrunnableobject2 = new MyRunnable(2000);
FutureTask
futureTask1 = new FutureTask<>(myrunnableobject1,
"FutureTask1 is complete");
FutureTask
futureTask2 = new FutureTask<>(myrunnableobject2,
"FutureTask2 is complete");
// create thread pool of 2 size for ExecutorService
ExecutorService executor = Executors.newFixedThreadPool(2);
// submit futureTask1 to ExecutorService
executor.submit(futureTask1);
// submit futureTask2 to ExecutorService
executor.submit(futureTask2);
while (true) {
try {
// if both future task complete
if (futureTask1.isDone() && futureTask2.isDone()) {
System.out.println("Both FutureTask Complete");
// shut down executor service
executor.shutdown();
return;
}
if (!futureTask1.isDone()) {
// wait indefinitely for future
// task to complete
System.out.println("FutureTask1 output = "
+ futureTask1.get());
}
System.out.println("Waiting for FutureTask2 to complete");
// Wait if necessary for the computation to complete,
// and then retrieves its result
String s = futureTask2.get(250, TimeUnit.MILLISECONDS);
if (s != null) {
System.out.println("FutureTask2 output=" + s);
}
}
catch (Exception e) {
Sysmtem.out.println("Exception: " + e);
}
}
}
}
输出:
FutureTask1 output=FutureTask1 is complete
Waiting for FutureTask2 to complete
Waiting for FutureTask2 to complete
Waiting for FutureTask2 to complete
Waiting for FutureTask2 to complete
FutureTask2 output=FutureTask2 is complete
Both FutureTask Complete
参考:
- https://docs.oracle.com/javase/7/docs/api/java Java
- https://docs.oracle.com/javase/7/docs/api/java Java