package com;
import java.util.concurrent.*;
/**
-
Callable and Future用法
-
Callable可以被ExecutorService的submit方法使用,可以取线程执行的返回值;
-
Future是返回值的封装类型:
-
get()方法阻塞当前线程直到获取到返回值
-
isDone()方法判断线程是否执行完成
-
isCancelled()方法判断线程是否被中断
-
cancel(boolean mayInterruptIfRunning)方法中断线程,但是线程方法内必须有中断判断interrupted(),否则是无法中断线程的
*/
public class TestCallableAndFuture {private static class Data{
public int sum;
}/**
-
Callable实现
*/
private static class TaskCall implements Callable{@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 0; i < 1000; i++) {
sum = sum+i;
}
return sum;
}
}
/**
-
Runnable实现,并且判断了线程是否被中断interrupted()
*/
private static class TaskRun implements Runnable{private Data data;
TaskRun(Data data){
this.data = data;
}@Override
public void run() {
for (int i = 0; i < 10000; i++) {
/**
* 判断线程如果被中断则跳出循环
*/
if (Thread.interrupted())
break;
data.sum = data.sum+i;
}
}
}
public static void main(String[] args) {
Data data = new Data();
/**
* 初始化一个可缓存线程池
/
ExecutorService executorService = Executors.newCachedThreadPool();
/*
* submit方法执行Callable
/
Future future1= executorService.submit(new TaskCall());
/*
* submit方法执行Runnable,其实future就是对data的封装,实际上使用future.get()返回的是data的引用
*/
Future future2 = executorService.submit(new TaskRun(data),data);try { System.out.println("future1 isCancelled:"+future1.isCancelled()); System.out.println("future1 result:"+future1.get()); System.out.println("future1 isDone:"+future1.isDone()); /** * 中断线程 */ //future2.cancel(true); if (!future2.isCancelled()) { System.out.println("future2 result:"+future2.get().sum); System.out.println("future2 isDone:"+future2.isDone()); } System.out.println(data.sum); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } System.out.println("完成");
}
} -
Callable和Runnbale一样代表着任务,区别在于Callable有返回值并且可以抛出异常。其使用如下:
Future接口
Future是一个接口,代表了一个异步计算的结果。接口中的方法用来检查计算是否完成、等待完成和得到计算的结果。当计算完成后,只能通过get()方法得到结果,get方法会阻塞直到结果准备好了。如果想取消,那么调用cancel()方法。其他方法用于确定任务是正常完成还是取消了。一旦计算完成了,那么这个计算就不能被取消。