在多线程开发中,经常会遇到在多线程中执行一段程序,如果N秒内执行完则返回结果,如果超出了N秒还没执行完则提示超时限制,以下是一个工具类,封装了超时逻辑。
工具类采用了jdk5才加入的FutureTask,因此必须运行在jdk5及以上版本的jdk中,另外本工具类不是线程安全的,所以使用时请采用new的方式来使用。
使用示例如下:
package com.tgb.lk.demo.thread.timeoutExecution;
import java.util.concurrent.TimeUnit;
/**
* Created by likun on 2014/9/26.
*/
public class TimeoutExecutionTest {
public static void main(String[] args) {
TimeoutExecution<Long> timeoutExecution = new TimeoutExecution<Long>() {
@Override
protected Long execute() throws Exception {
long millis = Math.round(10000 * Math.random());
Thread.sleep(millis);//这句替换为需要进行的处理
return millis;
}
};
if (timeoutExecution.execute(5, TimeUnit.SECONDS)) {
System.out.println("----------not timeout----------");
long result = timeoutExecution.getResult(); // 没有超时获得读取的数据长
System.out.println("result=" + result);
} else {
// 超时
System.out.println("----------timeout----------");
}
}
}
工具类如下:
package com.tgb.lk.demo.thread.timeoutExecution;
import java.util.concurrent.*;
/**
* 超时限制执行辅助类(线程不安全,使用时请创建新实例)
* <p/>
*/
public abstract class TimeoutExecution<T> implements Callable<T> {
private volatile Exception exception;
private T result;
/**
* 需要实现的具体执行内容
*
* @return 返回值
* @throws Exception 异常
*/
protected abstract T execute() throws Exception;
/**
* 超时限制执行
*
* @param timeout 超时时间数值
* @param unit 超时时间单位
* @return true没有超时正常返回结果,false超时,
*/
public boolean execute(int timeout, TimeUnit unit) {
result = null; //清除上次数据
FutureTask<T> futureTask = new FutureTask<T>(this);
boolean isNotTimeout = true;
try {
new Thread(futureTask).start();
result = futureTask.get(timeout, unit);
} catch (InterruptedException e) {
exception = e;
} catch (ExecutionException e) {
exception = (Exception) e.getCause();
} catch (TimeoutException e) {
isNotTimeout = false;
} finally {
futureTask.cancel(true);
}
return isNotTimeout;
}
@Override
public T call() throws Exception {
return execute();
}
public T getResult() {
return result;
}
public Exception getException() {
return exception;
}
}