【并发编程】- ThreadPoolExecutor使用cancel和isCancelled方法中断线程

169 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第8天,点击查看活动详情

接着上一篇的文章 【并发编程】- ThreadPoolExecutor使用submit方法提交Runnable任务定义执行结果的返回值类型

使用方法cancel(boolean mayInterruptIfRunning)和isCancelled()

如果线程任务没有执行完毕,则调用cancel()方法是什么情况呢?

public class TheCallable implements Callable<String> {
    private int number;

    public TheCallable(int number){
        super();
        this.number=number;
    }

    @Override
    public String call() throws Exception {
        Thread.sleep(5000);
        return "返回值:"+number;
    }
}

运行类代码如下:

@Slf4j
public class CancelCallableRun {
    public static void main(String[] args) {
        TheCallable theCallable = new TheCallable(20220804);
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 3, 5, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
        Future<String> future = threadPoolExecutor.submit(theCallable);
        log.info("取消任务结果:{},发送取消任务的命令执行结果:{}",future.cancel(true),future.isCancelled());
    }
}

运行结果如下:

15:06:30.197 [main] INFO com.ozx.concurrentprogram.executor.controller.CancelCallableRun - 取消任务结果:true,发送取消任务的命令执行结果:true

从运行结果看出任务在没有运行完成之前执行了cancel()方法返回为true,代表成功发送取消的命令。

此外之前使用参数mayInterruptIfRunning,它具有中断线程的作用,并且需要结合代码if(Thread.currentThread().isInterrupted())来进行实现。

线程执行代码如下:

@Slf4j
public class InterruptCallable implements Callable<String> {
    @Override
    public String call() throws Exception {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
        int i = 0;
        while(i == 0){
            if(Thread.currentThread().isInterrupted()){
                throw new InterruptedException();
            }
            log.info("线程正在运行中......");
        }
        return "返回值:"+simpleDateFormat.format(new Date());
    }
}

运行类代码没做任何修改,执行结果如下: 15:35:54.391 [pool-1-thread-1] INFO com.ozx.concurrentprogram.executor.service.InterruptCallable - 线程正在运行中......

15:35:54.391 [pool-1-thread-1] INFO com.ozx.concurrentprogram.executor.service.InterruptCallable - 线程正在运行中......

15:35:54.391 [pool-1-thread-1] INFO com.ozx.concurrentprogram.executor.service.InterruptCallable - 线程正在运行中......

15:35:54.391 [pool-1-thread-1] INFO com.ozx.concurrentprogram.executor.service.InterruptCallable - 线程正在运行中......

15:35:54.391 [pool-1-thread-1] INFO com.ozx.concurrentprogram.executor.service.InterruptCallable - 线程正在运行中......

15:35:54.541 [main] INFO com.ozx.concurrentprogram.executor.controller.InterruptCancelRun - 取消任务结果:true,发送取消任务的命令执行结果:true

从运行结果看出线程进入循环后执行任务,但是此时发送取消任务的命令,线程确实被中断了,不再继续执行下去了。