Java并发编程的Future

135244_Ezs2_255939.png

  1. 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;
}


转载于:https://my.oschina.net/u/255939/blog/532721

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值