前段时间在也博客里看的一篇博文是说掉用远程的webservice超时使得系统崩掉。并给出了一个设计,用于调用别人写的接口
基于著作权只保护作品思想表达方式而不保护思想本身 我自己重新重写了他给出的方法,我觉得他的思想非常值得学习。在系统设计中 任何输入都当成恶意的。
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/****
* 用于进黑洞抓取东西的函数猎狗
*
* @author
*
*/
public class FuncCourser {
private FuncCourser() {
}
private static ExecutorService executor = Executors
.newCachedThreadPool(new ThreadFactory() {
int nCount = 0;
public Thread newThread(Runnable task) {
nCount++;
Thread invokeThread = new Thread(task);
invokeThread.setName("Invoker-thread-" + nCount);
invokeThread.setDaemon(true);
return invokeThread;
}
});
/****
* 目标方法无返回值使用该方法调用
*
* @param task
* 调用代码
* @param unit
* 超时时间类
* @param timeout
* 时间
* @throws TimeoutException
* 调用超过指定的时间抛出此异常
*/
public static void call(Runnable task, TimeUnit unit, long timeout)
throws TimeoutException {
Future<?> futureResult = executor.submit(task);
try {
futureResult.get(timeout, unit);
} catch (Exception e) {
if (e instanceof TimeoutException) {
throw new TimeoutException("invoke timeout!");
}
throw new RuntimeException(e);
}
}
/*****
* 目标方法有返回值时使用该方法调用
*
* @param <T>
* @param task
* 调用代码
* @param unit
* 超时时间类型
* @param timeout
* 时间
* @return 被调用函数的返回值
* @throws TimeoutException
* 调用超过指定时间时抛出此异常
*/
public static <T> T call(Callable<?> task, TimeUnit unit, long timeout)
throws TimeoutException {
Future<?> futureResult = executor.submit(task);
Object callRet = null;
try {
callRet = futureResult.get(timeout, unit);
} catch (Exception e) {
if (e instanceof TimeoutException) {
throw new TimeoutException("invoke timeout!");
}
throw new RuntimeException(e);
}
return (T) callRet;
}
}
单调用其他人接口时使用子线程这样不会因为别人的方法死锁而照成系统蹦溃,这这种方法在多线程的环境中会产生很多的子线程照成许多内存占用,但对于安全来说这点牺牲值得。