通过前面几篇的学习,我们知道创建线程的方式有两种,一种是实现Runnable接口,另一种是继承Thread,但是这两种方式都有个缺点,那就是在任务执行完成之后无法获取返回结果,那如果我们想要获取返回结果该如何实现呢?还记上一篇Executor框架结构中提到的Callable接口和Future接口吗?,是的,从JAVA SE 5.0开始引入了Callable和Future,通过它们构建的线程,在任务执行完成后就可以获取执行结果,今天我们就来聊聊线程创建的第三种方式,那就是实现Callable接口。
public interface Runnable { public abstract void run(); }而Callable的接口定义如下
public interface Callable<V> { V call() throws Exception; }该接口声明了一个名称为call()的方法,同时这个方法可以有返回值V,也可以抛出异常。嗯,对该接口我们先了解这么多就行,下面我们来说明如何使用, 前篇文章我们说过,无论是Runnable接口的实现类还是Callable接口的实现类,都可以被ThreadPoolExecutor或ScheduledThreadPoolExecutor执行, ThreadPoolExecutor或ScheduledThreadPoolExecutor都实现了 ExcutorService接口, 而因此 Callable需要和Executor框架中的ExcutorService结合使用,我们先看看ExecutorService提供的方法:
<T> Future<T> submit(Callable<T> task); <T> Future<T> submit(Runnable task, T result); Future<?> submit(Runnable task);
public static Callable<Object> callable(Runnable task) public static <T> Callable<T> callable(Runnable task, T result)
public interface Future<V> { boolean cancel(boolean mayInterruptIfRunning); boolean isCancelled(); boolean isDone(); V get() throws InterruptedException, ExecutionException; V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException; }
public class FutureTask<V> implements RunnableFuture<V> {FutureTask类实现了RunnableFuture接口,我们看一下RunnableFuture接口的实现:
public interface RunnableFuture<V> extends Runnable, Future<V> { void run(); }
public FutureTask(Callable<V> callable) { } public FutureTask(Runnable runnable, V result) { }
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; } }Callable执行测试类如下:
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
主线程在执行完成
|
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(); // //提交任务并获取执行结果 // Future<Integer> future =es.submit(calTask); // //关闭线程池 // es.shutdown(); //创建线程池 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
主线程在执行完成
|