1、Future的核心思想是:一个方法f,计算过程可能非常耗时,等待f返回,显然不明智。可以在调用f的时候,立马返回一个Future,可以通过Future这个数据结构去控制方法f的计算过程。
这里的控制包括:
get方法:获取计算结果(如果还没计算完,也是必须等待的)
cancel方法:还没计算完,可以取消计算过程
isDone方法:判断是否计算完
isCancelled方法:判断计算是否被取消
2、Callable创建有返回值的线程
1、把耗时的网购厨具逻辑,封装到了一个Callable的call方法里面。
2、把Callable实例当作参数,生成一个FutureTask的对象,然后把这个对象当作一个Runnable,作为参数另起线程。
public class FutureCook {
static class Chuju{}
static class Shicai{}
static void cook(Chuju chuju, Shicai shicai){}
public static void main(String[] args) throws ExecutionException, InterruptedException {
long startTime = System.currentTimeMillis();
//1
Callable<Chuju> onlineShopping = new Callable<Chuju>() {
@Override
public Chuju call() throws Exception {
System.out.println("第一步,下单");
Thread.sleep(3000);
System.out.println("第一步,快递到");
return new Chuju();
}
};
FutureTask<Chuju> task = new FutureTask<Chuju>(onlineShopping);
new Thread(task).start();
//2
Thread.sleep(2000);//模拟购买食材
Shicai shicai = new Shicai();
System.out.println("第二步,食材到位");
//3
if (!task.isDone()) { // 联系快递员,询问是否到货
System.out.println("第三步:厨具还没到,心情好就等着(心情不好就调用cancel方法取消订单)");
}
Chuju chuju = task.get();
System.out.println("第三步,做菜");
cook(chuju, shicai);
System.out.println("总共用时" + (System.currentTimeMillis() - startTime) + "ms");
}
}
接下来提供一种改版的Future,不适用FutureTask而是Future接口,使用线程池对线程进行管理,代码如下:
import java.util.concurrent.*;
public class FutureCook {
static class Chuju{}
static class Shicai{}
static void cook(Chuju chuju, Shicai shicai){}
public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {
long startTime = System.currentTimeMillis();
//1
Future<Chuju> chujuTask = startTask();
//2
Thread.sleep(2000);//模拟购买食材
Shicai shicai = new Shicai();
System.out.println("第二步,食材到位");
//3
Chuju chuju = chujuTask.get(10000, TimeUnit.MILLISECONDS);
System.out.println("第三步,做菜");
cook(chuju, shicai);
System.out.println("总共用时" + (System.currentTimeMillis() - startTime) + "ms");
}
private static Future<Chuju> startTask(){
Callable<Chuju> onlineShopping = new Callable<Chuju>() {
@Override
public Chuju call() throws Exception {
System.out.println("第一步,下单");
Thread.sleep(3000);
System.out.println("第一步,快递到");
return new Chuju();
}
};
ExecutorService service = Executors.newCachedThreadPool();
Future<Chuju> future = service.submit(onlineShopping);
return future;
}
}