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

144 阅读2分钟

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

使用方法cancel(boolean mayInterruptIfRunning)和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){
                log.info("线程在休眠中...");
        }
        return "返回值:"+simpleDateFormat.format(new Date());
    }
}

修改运行类代码如下:

@Slf4j
public class InterruptCancelRun {
    public static void main(String[] args) {
        InterruptCallable interruptCallable = new InterruptCallable();
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 6, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
        Future<String> future = threadPoolExecutor.submit(interruptCallable);
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("取消任务结果:{},发送取消任务的命令执行结果:{}",future.cancel(true),future.isCancelled());
    }
}

运行结果如下:

16:24:56.302 [pool-1-thread-1] INFO com.ozx.concurrentprogram.executor.service.InterruptCallable - 线程在休眠中...

16:24:56.302 [pool-1-thread-1] INFO com.ozx.concurrentprogram.executor.service.InterruptCallable - 线程在休眠中...

16:24:56.302 [pool-1-thread-1] INFO com.ozx.concurrentprogram.executor.service.InterruptCallable - 线程在休眠中...

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

16:24:56.302 [pool-1-thread-1] INFO com.ozx.concurrentprogram.executor.service.InterruptCallable - 线程在休眠中...

16:24:56.302 [pool-1-thread-1] INFO com.ozx.concurrentprogram.executor.service.InterruptCallable - 线程在休眠中...

从运行结果看出线程并未发送取消命令而中断运行,返回值为true是代表了发送中断线程的命令是成功的,但是要中断要取决于有没有if(Thread.currentThread().isInterrupted())代码。

设置方法cancel传入的参数是false,线程运行情况如何?

线程执行代码如下:

@Slf4j
public class UseInterruptCallable implements Callable<String> {
    @Override
    public String call() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
        try {
        while( 1 == 1){
            if(Thread.currentThread().isInterrupted() == true){
                    throw new InterruptedException();
            }
            log.info("线程名:{},执行时间:{}",Thread.currentThread().getName(),simpleDateFormat.format(new Date()));

        }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "返回值:"+simpleDateFormat.format(new Date());
    }
}

运行类代码如下:

@Slf4j
public class InterruptCancelRun {
    public static void main(String[] args) {
        UseInterruptCallable interruptCallable = new UseInterruptCallable();
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 6, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
        Future<String> future = threadPoolExecutor.submit(interruptCallable);
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("取消任务结果:{},发送取消任务的命令执行结果:{}",future.cancel(false),future.isCancelled());
    }
}

运行结果如下:

10:24:59.172 [pool-1-thread-1] INFO com.ozx.concurrentprogram.executor.service.UseInterruptCallable - 线程名:pool-1-thread-1,执行时间:10:24:59 10:24:59.172 [pool-1-thread-1] INFO com.ozx.concurrentprogram.executor.service.UseInterruptCallable - 线程名:pool-1-thread-1,执行时间:10:24:59 10:24:59.173 [main] INFO com.ozx.concurrentprogram.executor.controller.InterruptCancelRun - 取消任务结果:true,发送取消任务的命令执行结果:true 10:24:59.175 [pool-1-thread-1] INFO com.ozx.concurrentprogram.executor.service.UseInterruptCallable - 线程名:pool-1-thread-1,执行时间:10:24:59 10:24:59.175 [pool-1-thread-1] INFO com.ozx.concurrentprogram.executor.service.UseInterruptCallable - 线程名:pool-1-thread-1,执行时间:10:24:59 10:24:59.175 [pool-1-thread-1] INFO com.ozx.concurrentprogram.executor.service.UseInterruptCallable - 线程名:pool-1-thread-1,执行时间:10:24:59 10:24:59.175 [pool-1-thread-1] INFO com.ozx.concurrentprogram.executor.service.UseInterruptCallable - 线程名:pool-1-thread-1,执行时间:10:24:59

从运行结果看来发送取消任务的命令执行结果为true,则代表成功发送取消的命令,但是因为cancel()方法参数值设置为false,所以线程并没有中断一直在运行。