在Java中,建立线程通常有两种方式,一种是继承Thread类,一种是实现Runnable接口。然而,这两种方式的缺点是在线程任务执行结束后,没法获取执行结果。咱们通常只能采用共享变量或共享存储区以及线程通讯的方式实现得到任务结果的目的。java
不过,Java中,也提供了使用Callable和Future来实现获取任务结果的操做。Callable用来执行任务,产生结果,而Future用来得到结果。网络
Callable接口的定义以下:多线程
public interface Callable<V> { /** * Computes a result, or throws an exception if unable to do so. * * @return computed result * @throws Exception if unable to compute a result */ V call() throws Exception; }
与Runnable接口不一样之处在于,call方法带有泛型返回值V。异步
Future模式的核心在于:去除了主函数的等待时间,并使得本来须要等待的时间段能够用于处理其余业务逻辑ide
Futrure模式:对于多线程,若是线程A要等待线程B的结果,那么线程A不必等待B,直到B有结果,能够先拿到一个将来的Future,等B有结果是再取真实的结果。函数
在多线程中常常举的一个例子就是:网络图片的下载,刚开始是经过模糊的图片来代替最后的图片,等下载图片的线程下载完图片后在替换。而在这个过程当中能够作一些其余的事情。线程
import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; /** * @author wn: * @version 上午16:53:57 * 类说明 */ public class ThreadCallTest { public static void main(String[]args){ ExecutorService executor=Executors.newCachedThreadPool(); Task task=new Task(); Future<Integer> result=executor.submit(task); if (executor != null) executor.shutdown(); try { System.out.println("call result"+result.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } System.out.println("over"); } } class Task implements Callable<Integer>{ @Override public Integer call() throws Exception { System.out.println("3.开始 ...."); Thread.sleep(3000); System.out.println("4.结束 ...."); return "xyz"; } }
当Task启动后不影响主线程运行,result.get()会等待3秒后返回结果xyzcode
V get() :获取异步执行的结果,若是没有结果可用,此方法会阻塞直到异步计算完成。继承
V get(Long timeout , TimeUnit unit) :获取异步执行结果,若是没有结果可用,此方法会阻塞,可是会有时间限制,若是阻塞时间超过设定的timeout时间,该方法将抛出异常。接口
boolean isDone() :若是任务执行结束,不管是正常结束或是中途取消仍是发生异常,都返回true。 => result.isDone()
boolean isCanceller() :若是任务完成前被取消,则返回true。
boolean cancel(boolean mayInterruptRunning) :若是任务还没开始,执行cancel(...)方法将返回false;若是任务已经启动,执行cancel(true)方法将以中断执行此任务线程的方式来试图中止任务,若是中止成功,返回true;
当任务已经启动,执行cancel(false)方法将不会对正在执行的任务线程产生影响(让线程正常执行到完成),此时返回false;
当任务已经完成,执行cancel(...)方法将返回false。mayInterruptRunning参数表示是否中断执行中的线程。
实际上Future提供了3种功能:
我的博客 蜗牛