1、Callable<V>接口
Runnable接口
public interface Runnable { public abstract void run(); }
Callable
public interface Callable<V> { V call() throws Exception; }
runnable接口 Callable接口 都可以被ThreadPoolExecutor或ScheduledThreadPoolExecutor执行,两者实现了ExcutorService接口
ExecutorService接口
<T> Future<T> submit(Callable<T> task); <T> Future<T> submit(Runnable task, T result); Future<?> submit(Runnable task);
2、Future<V>
获得异步计算结果,说白了就是对具体的Runnable或者Callable对象任务执行的结果进行获取(get()),取消(cancel()),判断是否完成等操作。
public interface Future<V> {
//如果任务没开始,cancle()将会返回true
//如果任务已经启动,执行cancle(true)将以中断执行此任务线程的方式来试图阻止任务,成功返沪true
//如果任务已经启动,执行cancle(false)将不会对执行线程产生影响,此时返回false boolean cancel(boolean mayInterruptIfRunning);
//如果任务完成前被取消,返回true boolean isCancelled();
//如果任务结束,无论是正常结束或是中途取消还是发生异常,都会true boolean isDone();
//获取异步执行结果,如果没有结果可用,此方法会阻塞直到异步计算完成。 V get() throws InterruptedException, ExecutionException;
//获取异步执行结果,如果没有结果可用,此方法会阻塞,
//但是会有时间限制,如果阻塞时间超过设定的timeout时间,该方法将抛出异常。 V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException; }
3、FutureTask类
public class FutureTask<V> implements RunnableFuture<V> {
其中
public interface RunnableFuture<V> extends Runnable, Future<V> { void run(); }
构造方法:
public interface RunnableFuture<V> extends Runnable, Future<V> { void run(); }
使用场景:
1、使用Callable+Future获取执行结果
package com.zejian.Executor; import java.util.concurrent.Callable; /** * @author zejian * @time 2016年3月15日 下午2:02:42 * @decrition Callable接口实例 */ public class CallableDemo implements Callable<Integer> { private int sum; @Override public Integer call() throws Exception { System.out.println("Callable子线程开始计算啦!"); Thread.sleep(2000); for(int i=0 ;i<5000;i++){ sum=sum+i; } System.out.println("Callable子线程计算结束!"); return sum; } }
package com.zejian.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; /** * @author zejian * @time 2016年3月15日 下午2:05:43 * @decrition callable执行测试类 */ public class CallableTest { public static void main(String[] args) { //创建线程池 ExecutorService es = Executors.newSingleThreadExecutor(); //创建Callable对象任务 CallableDemo calTask=new CallableDemo(); //提交任务并获取执行结果 Future<Integer> future =es.submit(calTask); //关闭线程池 es.shutdown(); try { Thread.sleep(2000); System.out.println("主线程在执行其他任务"); if(future.get()!=null){ //输出获取到的结果 System.out.println("future.get()-->"+future.get()); }else{ //输出获取到的结果 System.out.println("future.get()未获取到结果"); } } catch (Exception e) { e.printStackTrace(); } System.out.println("主线程在执行完成"); } }
执行结果:
Callable子线程开始计算啦! 主线程在执行其他任务 Callable子线程计算结束! future.get()-->12497500 主线程在在执行完成
2、使用Callable+FutureTask获取执行结果
package com.zejian.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.FutureTask; /** * @author zejian * @time 2016年3月15日 下午2:05:43 * @decrition callable执行测试类 */ public class CallableTest { public static void main(String[] args) { //创建线程池 ExecutorService es = Executors.newSingleThreadExecutor(); //创建Callable对象任务 CallableDemo calTask=new CallableDemo(); //创建FutureTask FutureTask<Integer> futureTask=new FutureTask<>(calTask); //执行任务 es.submit(futureTask); //关闭线程池 es.shutdown(); try { Thread.sleep(2000); System.out.println("主线程在执行其他任务"); if(futureTask.get()!=null){ //输出获取到的结果 System.out.println("futureTask.get()-->"+futureTask.get()); }else{ //输出获取到的结果 System.out.println("futureTask.get()未获取到结果"); } } catch (Exception e) { e.printStackTrace(); } System.out.println("主线程在执行完成"); } }
结果:
Callable子线程开始计算啦! 主线程在执行其他任务 Callable子线程计算结束! futureTask.get()-->12497500 主线程在执行完成