Future, future.cancel()可以删除同步阻塞任务
【Future】
http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/util/concurrent/Future.html
【好奇】
(1)future.cancel(mayInterruptIfRunning)的内部实现会是什么样子的?可以中断一个线程池里正在执行着的“那一个”任务。
可猜想,必定记录着具体线程标识,且发了一个中断信号。
(2)猜测,应该只是发一个中断信号,可以中断阻塞中的操作。而如果是while(true); 这样的占用CPU的非阻塞式操作,是中断不掉的,也即线程依旧在跑,占用着线程池资源。
【注意】
a). 线程池资源有限,有些任务会submit()不进去,抛异常:java.util.concurrent.RejectedExecutionException
b).只要submit()成功的,无论是线程正在执行,或是在BlockingQueue中等待执行,future.cancel()操作均可中断掉线程。也即,与其真正执行并无关系,阻塞中或等待被调度执行中,都将被中断。
【demo示例】
future.cancel中断阻塞操作:
public class Main {
/** 信号量 */
private Semaphore semaphore = new Semaphore(0); // 1
/** 线程池 */
private ThreadPoolExecutor pool = new ThreadPoolExecutor(3, 5, 3, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(3));
/** Future */
private Future<String> future ;
public void test(){
future = pool.submit(new Callable<String>() {
@Override
public String call() {
String result = null;
try {
// 同步阻塞获取信号量
semaphore.acquire();
result = "ok";
} catch (InterruptedException e) {
result = "interrupted";
}
return result;
}
});
String result = "timeout";
try {
// 等待3s
result = future.get(3, TimeUnit.SECONDS);
}catch (Exception e) {
System.out.println("超时异常");
}
// 删除线程池中任务
boolean cancelResult = future.cancel(true);
System.out.println("result is " + result);
System.out.println("删除结果:" +cancelResult);
System.out.println("当前active线程数:" +pool.getActiveCount());
}
public static void main(String[] args) {
Main o = new Main();
o.test();
}
}