测试代码
代码如下
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 ThradPoolTest {
private static ExecutorService executor = Executors.newCachedThreadPool();
protected static int SLEEP_TIME = 2000;
/**
* @param args
*/
public static void main(String[] args) {
Boolean result =null;
Future<Boolean> timeOutfuture = executor.submit(new TestJob(SLEEP_TIME*2));
System.out.println("==========timeOutfuture test==============");
try {
result = timeOutfuture.get(SLEEP_TIME, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
System.out.println("Time is out");
timeOutfuture.cancel(true);
}
System.out.println(result);
Future<Boolean> normalFuture = executor.submit(new TestJob(SLEEP_TIME/2));
System.out.println("==========normalFuture future test==============");
try {
result = normalFuture.get(SLEEP_TIME, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
System.out.println("Time is out");
normalFuture.cancel(true);
}
System.out.println(result);
executor.shutdown();
}
// 实现Callable接口
static class TestJob implements Callable<Boolean> {
private int workTime;
public TestJob(int workTime){
this.workTime = workTime;
}
@Override
public Boolean call() {
long startTime = System.currentTimeMillis();
while(true){
for (; System.currentTimeMillis() - startTime < workTime; ) {
doSomeThing();
//判断是否中断
if (Thread.interrupted()){
return false;
}
}
//任务完成返回
return true;
}
}
//进行必要的处理
public void doSomeThing(){}
}
说明:实际上在doSomeThing的方法的实现也很重要,如果这个地方完全阻塞,那么实际上到不了Thread.interrupted()检测的这个方法,线程无法中断。
JDK FutureTask的canel分析
public boolean cancel(boolean mayInterruptIfRunning) {
if (state != NEW)
return false;
if (mayInterruptIfRunning) {
if (!UNSAFE.compareAndSwapInt(this, stateOffset, NEW, INTERRUPTING))//NEW设置为INTERRUPTING状态
return false;
Thread t = runner;
if (t != null)
t.interrupt();
UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED); // final state,设置为INTERRUPTED
}
else if (!UNSAFE.compareAndSwapInt(this, stateOffset, NEW, CANCELLED))//如果已经INTERRUPTED,返回false
return false;
finishCompletion();//完成收尾工作
return true;
}
说明
1. finishCompletion通知相关waiters进行unpark
2. waiters为future的一个成员变量,Future中的get方法,将当前的线程增加到waiters中,并park自己
3. waiters为FutureTask中的一个成员变量,为等待队列的队列头
参考文档
http://stackoverflow.com/questions/17233038/how-to-implement-synchronous-method-timeouts-in-java
http://stackoverflow.com/questions/2275443/how-to-timeout-a-thread