Future, future.cancel()可以删除同步阻塞任务

【Future】

Future, future.cancel()可以删除同步阻塞任务_第1张图片

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();
	}
}


你可能感兴趣的:(future)