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

并发包之Future:代码级控制超时时间

2014-05-21 03:16 381 查看
先谢Doug Lea。

使用场景:

最近在做webservice调用的时候,发现一个问题,对方的webservice接口很不稳定,所以在获取的数据时候经常要等待很久才能把数据全部拉回来,甚至有时候直接就抛异常了,这种阻塞很耗费时间,性能很低。针对这种情况,我需要将一定时间内没有返回结果的调用KILL掉,于是用到了并发包Future,实现并在生产环境运行良好。

============================================================

2015-07-13修改备注:

1、之前的代码存在executor没有关闭的异常;

2、对新来的朋友提个建议,频繁创建single线程池不是一个好建议。我之前的场景并发很低,看不出问题。随着现在接触的业务并发变得很大,根本不会这么写了,因为频繁的创建关闭线程会浪费很多资源。并发很小的情况,并且必须要控制超时时间的情况下可以试试。

很抱歉,本人阅历有限,希望没对读者造成影响。

============================================================

测试代码如下,自行体会:

package com.array7.concurrent;

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;

public class FutureTest {
public static void main(String[] args) {
String result = ControlTimeOut.call(new CallableImpl("OK"));
System.out.println(result);
result = ControlTimeOut.call(new CallableImpl("NO OK!"));
System.out.println("result=" + result);
}
}
class ControlTimeOut {
@SuppressWarnings("unchecked")
public static <T> T call(Callable<T> callable) {
ExecutorService executor = Executors.newCachedThreadPool();
Future<T> future = executor.submit(callable);
try {
T t = future.get(3000, TimeUnit.MILLISECONDS);
executor.shutdwon();
return t;
} catch (InterruptedException e) {
System.out.println("InterruptedException");
} catch (ExecutionException e) {
System.out.println("ExecutionException");
} catch (TimeoutException e) {
// TODO: coding here...
System.out.println("TimeoutException");
}
return null;
}

}

class CallableImpl implements Callable<String> {
private static final String CORRECT_KEY = "OK";
private String key = "";

public CallableImpl(String key) {
this.key = key;
}

public String call() {
// TODO:真正的业务逻辑
if (CORRECT_KEY.equals(this.getKey())) {
return "SUCCESS";
} else {
try {
Thread.sleep(5000);	// 阻塞。设置5秒超时,为了Future抛出TimeoutException
} catch (InterruptedException e) {
e.printStackTrace();
}
return "FAIL";
}
}

public String getKey() {
return key;
}

public void setKey(String key) {
this.key = key;
}
}


版权声明:本文为博主原创文章,未经博主允许不得转载。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: