FutureTask的cancel方法真的能停止掉一个正在执行的异步任务吗

本文探讨了Java中FutureTask的cancel方法,并介绍如何通过在循环条件中加入Thread.currentThread().isInterrupted()判断来实现线程的有效中断。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


		ExecutorService executor = Executors.newSingleThreadExecutor();
		FutureTask<?> futureTask = new FutureTask<String>(new Callable<String>() {
			@Override
			public String call() throws Exception {
				for(int i=0;i<10000;i++){
					System.out.println(i);
				}
				return null;
			}
		});
		executor.execute(futureTask);
		System.out.println("futureTask start");
		try {
			Thread.sleep(10);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		futureTask.cancel(true);
		System.out.println("futureTask cancel");
	}

我们先来看看这个例子,发现最终执行结果是9999,即异步任务并没有被cancel而是一直执行完毕,这样看来这个cancel方法有点名不副实啊。

其实我们如果查看FutureTask的源码就会发现cancel只不过是调用了Thread的interrupt方法,而interrupt只能是停掉线程中有sleep,wait,join逻辑的线程,抛出一个InterruptException。这样看来FutureTask的cancel方法并不能停掉一切正在执行的异步任务。但是这里我们有一个妥协的做法就是在判断条件中加!Thread.currentThread().isInterrupted()这个判断即可

ExecutorService executor = Executors.newSingleThreadExecutor();
		FutureTask<?> futureTask = new FutureTask<String>(new Callable<String>() {
			@Override
			public String call() throws Exception {
				for(int i=0;i<10000&&!Thread.currentThread().isInterrupted();i++){
					System.out.println(i);
				}
				return null;
			}
		});
		executor.execute(futureTask);
		System.out.println("futureTask start");
		try {
			Thread.sleep(10);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		futureTask.cancel(true);
		System.out.println("futureTask cancel");

最终这个就可以真正的结束异步任务。

  到这里我们可以发现Java中并没有可以真正中断线程的方法,早期的stop已经不推荐使用,而interrupt方法也需要代码片段中有sleep,wait,join这些方法的调用,否则不能停止线程,现在java推荐的方式就是将run方法执行完,这就需要我们在while循环中加一个标志来控制退出,不过我们不需要额外设置这个标志,只需要调用thread的isInterrupted()方法判断,这样外界就可以调用该线程的isInterrupted方法来停止现在了,不用额外添加标志。

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值