由于Future模式在平常看到的代码中用的比较多,所以就先小结下这个模式,后面再来看并发容器中的集合类。
JDK中的Future模式:
Future,既是未来的意思,那么这个模式的意思呢,就是说这个任务我现在并不会马上做完,你现在先去做点别的,等我做好了再通知你,联系“未来“ 这个词的意思就是说在将来的某个时刻,我把东西做好了,然后再返回给你。
先来看一下类图:
(FutureTask 和 Callable之间应该还有一个依赖关系,但是)
通过类图我们可以知道:
Future是一个接口,拥有get方法,你通过get()方法可以可以取得返回值,而RunnableFuture接口 在继承Future接口的同时又继承了Runnable接口,那么RunnableFuture又可以作为Runnable对象开启一个线程,FutureTask类则实现了这些方法。
代码演示:
用了官网的代码,为了方便演示添加了一些输出的语句
import java.util.concurrent.*; public class Lesson01_Future { public static void main(String[] args) throws InterruptedException { Callable searcher = new Callable() { @Override public String call() throws Exception { System.out.println("一个耗时大概5s的操作开始暗中进行 "); StringBuilder sb = new StringBuilder(); for (int i = 0; i < 5; i++) { sb.append(i); Thread.sleep(1000); } return sb.toString(); } }; ExecutorService excutor = Executors.newFixedThreadPool(1); FutureTask<String> future = new FutureTask<String>(searcher); //这里searcher就开始执行了 excutor.submit(future); Thread.sleep(100); //确保searcher已经开始执行 //在searcher执行的时候,我们可以去干点别的 //使用一个sleep方法模拟一个耗时操作 System.out.println("等待的时候咱们干点别的,"); for (int i = 0; i < 3 ; i++) { System.out.println("other things: " + (i+1) + "s"); Thread.sleep(1000); } System.out.println("other things 搞定,现在去看看耗时的操作搞完没 "); //现在再来看它搞定没,搞定了就输出它的值 //注意没搞定的话,线程就必须阻塞在这里等着它搞定,不能继续去做其他的事情了 try { if(future.isDone()) { System.out.println("耗时的操作已经完成,结果是:" + future.get()); } else { System.out.println("耗时操作还没有完成,咱们再等等"); System.out.println("耗时的操作已经完成,结果是:" + future.get()); } } catch (ExecutionException e) { e.printStackTrace(); } excutor.shutdown(); } }
向线程池提交searcher之后,模拟的耗时操作就开始进行了,然后主线程还是可以执行其他的任务,但是一旦你使用了future.get()方法,线程就必须阻塞住直到future返回结果为止。
最后的执行结果:
一个耗时大概5s的操作开始暗中进行 等待的时候咱们干点别的, other things: 1s other things: 2s other things: 3s other things 搞定,现在去看看耗时的操作搞完没 耗时操作还没有完成,咱们再等等 耗时的操作已经完成,结果是:01234 Process finished with exit code 0