Java并发编程的Future
2015-11-19 00:00
309 查看
Future 基本概念
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; }
future 代表一个异步执行的结果,future 提供了一些方法来检查是否执行完成,是否取消等操作。并且只能通过get()来获取执行的结果,如果计算没有完成就一直阻塞,知道完成计算,除非执行线程被中断或者出现异常。
1.1结果的获取
future.get(long timeout, TimeUnit unit)throws InterruptedException, ExecutionException, TimeoutException;
这个方法可以设置get的过期时间,在超过一定时间时,结果已经没有必要,就应该取消关闭这个任务线程,来节省资源,超时会抛出TimeoutException 同过捕获这个异常后future.cancel(true)来关闭这个任务,这个true表示如果线程在运行,是否终止正在执行线程的服务
TimeUnit翻译的话就是时间单位,在这里的用处例如
future.get(50,TimeUnit.MILLISECONDS)表示在50毫秒后超时 future.get(50,TimeUnit.SECONDS)表示在50秒以后超时
所以TimeUnit在这里就是指明时间的单位
2.FutureTask
一个可以取消异步的计算任务,他是接口future的一个基本的实现。更具上面的uml图可以看出,Future继承自RunnableFuture,而RunnableFuture同时继承了Runnable和Future接口,所以FutureTask 可以被用来包装一个Callable或者Runable对象,所以 FutureTask 可以被提交的Executor执行,也可以new一个线程运行start()来执行,实质是一样的。
3.应用的场景
比如在进行分页查询时,要执行2条sql语句,一条来统计所有的数量,一条来获取一页的记录数,所以可以将统计数量的一条语句放到另一条线程中执行,然后通过FutureTask 来包装,提交到线程中执行,然后可以通过get方法来获取执行完成的结果。
public Page<T> restPage(@ParameterValueKeyProvider String key,final String hql,final Page<T> page) { Query query=getNSession().createQuery(hql); Map<String, Object> params=page.getParams(); for(int i=0;i<page.getParamsOrder().size();i++){ query.setParameter(i, params.get(page.getParamsOrder().get(i))); } int rowCount=0; String rowKey=ProjectUtils.getRowCountKey(hql, page.getParams()); FutureTask<Integer> rowCounTask; query.setFirstResult(((page.getCurrentPage()-1)<0?0:(page.getCurrentPage()-1))*13); query.setMaxResults(13); List<T> list; if(MemcachedUtils.get(rowKey)!=null){ rowCount=Integer.parseInt(MemcachedUtils.get(rowKey).toString()); list=query.list(); }else{ rowCounTask=new FutureTask<>(new Callable<Integer>() { @Override public Integer call() throws Exception { return getRowCount(hql, page); } }); Thread thread=new Thread(rowCounTask); thread.start(); list=query.list(); try { rowCount=rowCounTask.get(); } catch (InterruptedException e) { e.printStackTrace(); rowCount=getRowCount(hql, page); } catch (ExecutionException e) { e.printStackTrace(); rowCount=getRowCount(hql, page); } MemcachedUtils.set(rowKey, rowCount, new Date(1000*300)); } page.initPage(13, rowCount, page.getCurrentPage()); page.setResult(list); return page; }
相关文章推荐
- java I/O案例
- Java写入文件的几种方法小结
- 提升Java性能的基本方法
- javaweb
- Java中的final关键字
- Java 注释
- Java 注释
- Java 注释
- Myeclipse改变工作区背景颜色
- No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK
- JAVA基础课总结九
- Java Socket通信实现带联机功能的俄罗斯方块
- JAVA基础课总结八
- Java中的冒泡排序原理及实现方法
- java中的栈 Staack
- Java parseInt实现
- Spring中id和idref属性的区别
- java高效的文件复制方法
- 0. Spring4.1-环境搭建
- Java log日志输出