一、Callable介绍
1.1 Runnable介绍
Runnable是一个接口,里面声明了run方法。但是由于run方法返回值类型为void,所以在执行完成任务后,无法返回任何结果。
@FunctionalInterface
public interface Runnable {public abstract void run();
}
1.2 Callable介绍
callable位于java.util.concurrent包下,它是一个接口,这个接口下面只有一个call()方法。它是一个泛型接口,可以有返回值,也可以抛出异常
public interface Callable<V> {V call() throws Exception;
}
二、怎么使用Callable?
2.1 借助FutureTask执行
2.1.1 Future介绍
Future是一个接口,它可以对于具体的Runnable获取Callable任务的执行结果进行取消,查询是否完成,获取结果。必要时可以通过get()方法获取执行结果,该方法会阻塞直到任务返回结果。
2.1.2 Future源码解析
package java.util.concurrent;public interface Future<V> {/*** 用来取消任务,如果取消任务成功,就返回true,如果失败,就返回false* @param mayInterruptIfRunning 表示是否取消正在执行却没有执行完毕的任务,如果设置了ture,则表示可以* 取消正在执行过程中的任务* 如果任务正在执行,若mayInterruptIfRunning为ture,则返回true,若mayInterruptIfRunning为ture为false* 不会取消任务,返回false,如果任务还没有执行,不管若mayInterruptIfRunning为ture还是false,都返回ture* 如果任务已完成,则无论不管若mayInterruptIfRunning为ture还是false,一定返回false*/boolean cancel(boolean mayInterruptIfRunning);/*** 如果此任务在正常完成之前被取消,则返回true*/boolean isCancelled();/*** 如果此任务完成,则返回true*/boolean isDone();/*** 等待任务完成,然后返回其结果,是一个阻塞的方法*/V get() throws InterruptedException, ExecutionException;/*** 如果在指定的时间内,还没有获取到结果,则返回null*/V get(long timeout, TimeUnit unit)throws InterruptedException, ExecutionException, TimeoutException;}
2.1.3 总结
- Future能够判断任务是否完成
- Future能够中断任务执行
- Future获取任务执行结果
2.1.3 FutureTask介绍
- 由于Future是一个接口,无法用来直接创建对象使用,所以我们在使用过程中一般都是通过FutureTask来进行实现
- FutureTask类实现了RunnableFuture接口,而RunnableFuture接口继承了Runnable和Future接口,所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable返回值。
- FutureTask可以用来包装Callable或者Runnable对象。因为FutureTask实现了Runnable接口,所以FutureTask也可以提交给Executor
2.1.4 FutureTask三种状态
- 未启动:创建了FutureTask对象,但FutureTask.run()还未执行之前
- 已启动:FutureTask对象的run启动并执行过程中
- 已完成:FutureTask正常结束,或者FutureTask执行被取消(FutrueTask对象的cancel方法),或者FutureTask对象run方法执行抛出异常导致中断而结束,FutureTask都处于已完成的状态
2.2.1 Callable使用案例
Callable使用方式有两种,一种是通过线程池,一种是线程直接调用
线程池介绍和线程池工具类代码
线程池工具类_java线程池工具类-CSDN博客
public class MyCallable implements Callable{@Overridepublic Object call() throws Exception {System.out.println("开始对0—100和计算");int sum = 0;for (int i = 0;i < 101; i++) {sum = sum + i;}return sum;}
}
public class MyCallableTest {public static void main(String[] args) throws ExecutionException, InterruptedException {MyCallable myCallable = new MyCallable();System.out.println("----------------利用线程池进行调用---------------------");Future<Integer> future = ThreadPoolUtils.submit(myCallable);System.out.println(future.get());System.out.println("-----------------FutureTask调用------------------------");FutureTask futureTask = new FutureTask(myCallable);//new Thread(futureTask).start();futureTask.run();System.out.println(futureTask.get());}
}
2.2.2 执行结果
参考文档:FutureTask详解-CSDN博客
JAVA多线程—Callable详解_callable java-CSDN博客