java - future

FutureTask可用于异步获取执行结果或取消执行任务的场景。通过get()方法可以异步获取执行结果,不论FutureTask调用多少次run()或者call()方法,它都能确保只执行一次Runable或Callable任务。因此,FutureTask非常适合用于耗时高并发的计算,另外可以通过cancel()方法取消执行任务。

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
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;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;


/**
 * 为任务设置时限
 * 
 * 为任务设置预期完成时间,如果get超时,取消任务,并使用模式的信息取代它
 * 
 * f.get(timeout, unit)
 * future.get("预期时间值","预期时间单位"),如果超过指定的预期返回时间还不能返回结果,那么就会抛出TimeoutException的异常
 * 
 * f.get()如果不带参数,那么会堵塞直到返回结果
 * @author 
 *
 */
public class TimeoutThread {

	    //固定大小的线程池,同时只能接受5个任务
		static  ExecutorService mExecutor = Executors.newFixedThreadPool(5);
		final static long timeout = 4 ;
		
	    /**
	     * 模拟在预定时间内获取广告信息
	     * @throws InterruptedException
	     */
		static void rederPageWithAd(final String pageTitle)  throws  InterruptedException{
			Future<String> f = mExecutor.submit(new Callable<String>() {
				@Override
				public String call() throws Exception {
					System.out.println("开始加载广告信息");
					int randomTime = new Random().nextInt(5) + 1;//限制耗时不会出现0s,不会大于10s
					Thread.sleep(randomTime * 1000);
					System.out.println("正常加载广告耗时:" + randomTime +"s");
					return pageTitle;
				}
			});
			
			String page;
			try {
				//在预计时间内等待
				System.out.println("预期任务执行完时间:" + timeout + "s");
				//page = f.get();
				page = f.get(timeout, TimeUnit.SECONDS);
			} catch (ExecutionException e) {
				page = "出现执行异常,显示默认的广告页面";
			} catch (TimeoutException e) {
				page = "任务执行超时,显示默认的广告页面";
				f.cancel(true);//取消没有执行完的任务,设置为ture说明任务能被中断,否则执行中的任务要完成
			}
			System.out.println("成功加载广告页面:" + page);
			
	
		}
		
		
		public static void main(String[] args) {
			try {
				List<String> titleList = new ArrayList<String>();
				titleList.add("体育赛事");
				titleList.add("娱乐新闻");
				titleList.add("实时聚焦");
				titleList.add("国际咨询");
				titleList.add("影视天下");
				titleList.add("游戏风云");
				for (String string : titleList) {
					rederPageWithAd(string);
				}
				
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally{
		            /**
			     * 只有执行了shutdown方法,执行isTerminated才有效。否则isTerminated一直为ture
			     */
			    mExecutor.shutdown();
			    while(true){
					if(mExecutor.isTerminated()){
						System.out.println("所有任务都执行完了,关闭线程池");
						break;
					}
				}
			}
			
		}
	
}

在网络上看了很多,只有这个例子,表示得最清楚,虽然没办法成功的引入到我现在的项目中使用,但是很好的帮助了我对future机制的和适应场景的理解;

posted @ 2022-01-27 18:36  zhangdaopin  阅读(30)  评论(0编辑  收藏  举报