您的位置:首页 > 编程语言 > Java开发

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: