版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014252478/article/details/83586221
1、Callable类似于Runnable,为线程设计。区别在于,callable有返回值future,而Runnable则不会有返回值,同时Runnable不会抛出异常。future用于记录线程是否完成,不能用于判断线程执行是否正确。
关于callable实例:
public class CallableAndFuture {
public static void main(String[] args) {
ExecutorService threadPool = Executors.newSingleThreadExecutor();// 创建一个线程即可
Future<String> future = threadPool.submit(
new Callable<String>() {
@Override
public String call() throws Exception {
Thread.sleep(2000);
return "hello";
}
}
);
System.out.println("等待结果:");
try {
System.out.println("拿到结果:" + future.get());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
关于产生future,还有
private ScheduledExecutorService pool = Executors.newScheduledThreadPool(3);
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //没有精确到毫秒
public void scheduledStatusNotify() {
ScheduledFuture<?> future = pool.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
..........
}
});
}
2、在起多个线程的时候,可以将线程池扔进CompletionService<T>接口中,当需要查看多个返回值结果时,可以从当中取出来:
public class CallableAndFuture {
public static void main(String[] args) {
ExecutorService threadPool = Executors.newCachedThreadPool();//定义一个缓存线程池
CompletionService<Integer> completionService =
new ExecutorCompletionService<Integer>(threadPool); //将线程池扔进去
for(int i = 1; i <= 5; i ++) {
final int seq = i;
completionService.submit( //用里面装的线程去执行这些任务,每个线程都会返回一个数据
new Callable<Integer> () {
@Override
public Integer call() throws Exception {
Thread.sleep(new Random().nextInt(5000));
return seq;
}
}
);
}
for(int i = 0; i < 5; i ++) { //执行完了后,再取出来
try {
System.out.print(completionService.take().get() + " ");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
ExecutorCompletionService的实现相当直观。它在构造函数中创建一个BlockingQueue,用它去保持完成的结果。 计算完成时会调用FutureTask中的done方法。
当提交一个任务后,首先把这个任务包装为一个QueueingFuture,它是 FutureTask的一个子类,然后覆写done方法,将结果置入BlockingQueue中,take和poll方法委托给了 BlockingQueue,它会在结果不可用时阻塞。