Future and Callable
1. Runnable的缺陷
- 不能返回一个返回值
- 不能抛出异常
2.Callable接口
3. Future类
4. 用法1: 线程池的submit方法返回Future对象
/**
* @Classname OneFuture
* @Description 演示一个Future的简单使用方法
* @Date 2021/3/1 16:52
* @Created by YoungLiu
*/
public class OneFuture {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService service = Executors.newFixedThreadPool(10);
Future<Integer> future = service.submit(new CallableTask());
System.out.println(future.get());
}
static class CallableTask implements Callable<Integer>{
@Override
public Integer call() throws Exception {
Thread.sleep(3000);
return new Random().nextInt();
}
}
}
/**
* @Classname OneFuture
* @Description 演示一个Future的简单使用方法,Lambda
* @Date 2021/3/1 16:52
* @Created by YoungLiu
*/
public class OneFutureLambda {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService service = Executors.newFixedThreadPool(10);
Callable<Integer> callable = ()->{
Thread.sleep(3000);
return new Random().nextInt();
};
Future<Integer> future = service.submit(callable);
System.out.println(future.get());
}
}
/**
* @Classname MultiFutures
* @Description 演示批量提交任务时,用List来批量接收任务
* @Date 2021/3/1 17:02
* @Created by YoungLiu
*/
public class MultiFutures {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService service = Executors.newFixedThreadPool(2);
ArrayList<Future> futures = new ArrayList<>();
for (int i = 0; i < 20; i++) {
Future<Integer> future = service.submit(new CallableTask());
futures.add(future);
}
Thread.sleep(5000);
for (int i = 0; i < 20; i++) {
Future<Integer> future = futures.get(i);
Integer j =(Integer) future.get();
System.out.println(j);
}
}
static class CallableTask implements Callable<Integer>{
@Override
public Integer call() throws Exception {
Thread.sleep(3000);
return new Random().nextInt();
}
}
}
/**
* @Classname Timeout
* @Description 演示get的超时方法,需要注意超时后处理,调用future.cancel()。
* 演示cancel传入true和false的区别,代表是否中断正在执行的任务。
* @Date 2021/3/1 17:35
* @Created by YoungLiu
*/
public class Timeout {
private static final Ad DEFAULT_AD = new Ad("无网络时候的默认公司");
private static final ExecutorService service = Executors.newFixedThreadPool(10);
static class Ad {
String name;
public Ad(String name) {
this.name = name;
}
@Override
public String toString() {
return "Ad{" +
"name='" + name + '\'' +
'}';
}
}
static class FetchAdTask implements Callable<Ad> {
@Override
public Ad call() throws Exception {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
System.out.println("sleep期间被中断");
return new Ad("被中断时候的默认广州");
}
return new Ad("旅游订票哪家强?找xx");
}
}
public void printAd() {
Future<Ad> f = service.submit(new FetchAdTask());
Ad ad;
try {
ad = (Ad) f.get(2000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
ad = new Ad("被中断时候的默认广告");
e.printStackTrace();
} catch (ExecutionException e) {
ad = new Ad("异常时候的默认广州");
e.printStackTrace();
} catch (TimeoutException e) {
ad = new Ad("超时时候的默认广告");
System.out.println("超时,为了获取到广告");
//取消成功 返回true 取消失败 false
boolean cancel = f.cancel(false);//如果参数是true,会把线程中断
System.out.println("cancel的结果" + cancel);
}
service.shutdown();
System.out.println(ad);
}
public static void main(String[] args) {
Timeout timeout = new Timeout();
timeout.printAd();
}
}
5. 用法2: 用FutureTask来创建Future
/**
* @Classname FutureTaskDemo
* @Description 演示FutureTask的用法
* @Date 2021/3/1 18:08
* @Created by YoungLiu
*/
public class FutureTaskDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
Task task = new Task();
FutureTask<Integer> integerFutureTask = new FutureTask<>(task);
// new Thread(integerFutureTask).start();
ExecutorService service = Executors.newFixedThreadPool(10);
service.submit(integerFutureTask);
Integer integer = integerFutureTask.get();
System.out.println("futuretask运行结果"+integer);
}
static class Task implements Callable<Integer>{
@Override
public Integer call() throws Exception {
System.out.println("子线程正在计算");
Thread.sleep(3000);
int sum=0;
for (int i = 0; i < 100; i++) {
sum+=i;
}
return sum;
}
}
}
6.Future的注意点