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机制的和适应场景的理解;