JDK8和JDK17 Thread.interrupt() 实现区别

一、Interrupt打断阻塞

以下相同的代码分别在JDK8和JDK17中执行会得到不同的结果,基于两个不同的实现版本源码是不一样的,JDK17在调用interrupt方法时会将interrupted设置为true,JDK8不会进行设置。当前线程在调用sleep()、wait()、join()方法时被阻塞,则其中断状态将被清除,并且将会抛出InterruptedException

package com.kh.JUC;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class Interrupt {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
            log.info("sleep");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }, "t");
        t.start();
        Thread.sleep(1000); // 不进行sleep的话会先执行main线程的输出再执行t线程
        log.info("Interrupt");
        t.interrupt();
        log.info("Is Interrupt: " + t.isInterrupted());
    }
}

二、JDK8执行结果

三、JDK17执行结果:

四、JDK8实现

五、JDK17实现

该方法用于中断线程。主要逻辑如下:
检查当前线程是否有权限中断目标线程,若无权限则抛出SecurityException。
如果线程在等待或阻塞状态,清除中断状态并抛出InterruptedException。
如果线程在I/O操作上被阻塞,则关闭通道并设置中断状态。
如果线程在选择器上被阻塞,则立即返回并设置中断状态。
如果以上条件都不满足,则仅设置中断状态。

<think>我们是在JDK 8环境下,而CompletableFuture在JDK 8中并没有直接提供超时控制的方法(如orTimeout()是在JDK 9引入的)。因此,我们需要自己实现超时控制。 思路: 1. 使用一个额外的调度线程池(ScheduledExecutorService)来在指定时间后触发超时。 2. 如果原始任务在超时前完成,则取消超时任务。 3. 如果超时先发生,则主动完成CompletableFuture并设置超时异常。 步骤: a. 创建原始CompletableFuture,执行异步任务。 b. 创建另一个CompletableFuture(timeoutFuture),由调度线程池在延迟指定时间后触发,并抛出超时异常。 c. 使用CompletableFuture的applyToEither方法,即原始任务超时任务哪个先完成就取哪个结果。 但是注意,超时任务完成时是抛出异常,所以当超时发生时,整个结果就会抛出异常。 具体实现: 注意:由于JDK8的CompletableFuture没有completeOnTimeoutorTimeout方法,我们需要自己模拟。 代码示例: 首先,我们定义一个工具方法,为给定的CompletableFuture添加超时控制:</think>### JDK 8实现 `CompletableFuture.supplyAsync()` 超时控制 在 JDK 8 中,`CompletableFuture` 原生不支持超时控制(该功能在 JDK 9+ 通过 `orTimeout()` 实现)。以下是三种可靠的实现方案: --- #### 方案一:结合 `ScheduledExecutorService`(推荐) ```java ExecutorService taskPool = Executors.newFixedThreadPool(4); ScheduledExecutorService timeoutPool = Executors.newScheduledThreadPool(2); CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { // 模拟耗时操作 Thread.sleep(3000); return "Result"; }, taskPool); // 设置超时控制(3秒) CompletableFuture<String> timeoutFuture = new CompletableFuture<>(); timeoutPool.schedule(() -> { timeoutFuture.completeExceptionally(new TimeoutException("Task timed out")); }, 3, TimeUnit.SECONDS); // 组合结果 CompletableFuture<String> result = future.applyToEither(timeoutFuture, Function.identity()) .exceptionally(ex -> { System.err.println("Error: " + ex.getMessage()); return "Fallback Value"; }); System.out.println(result.get()); // 输出结果或超时信息 ``` **关键点**: 1. 使用两个独立线程池:任务线程池 + 超时调度池[^2] 2. `applyToEither()` 优先取最先完成的结果 3. `exceptionally()` 处理超时异常 4. 资源清理:最后调用 `shutdown()` 关闭线程池 --- #### 方案二:手动超时检测(简单场景) ```java CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { try { Thread.sleep(5000); // 模拟5秒任务 return "Success"; } catch (InterruptedException e) { Thread.currentThread().interrupt(); return "Interrupted"; } }); try { // 阻塞获取结果(最多等待2秒) String result = future.get(2, TimeUnit.SECONDS); System.out.println(result); } catch (TimeoutException e) { future.cancel(true); // 取消任务 System.out.println("Timeout occurred"); } ``` **适用场景**:简单异步任务,无需复杂链式调用 --- #### 方案三:包装工具类(可复用) ```java public class FutureTimeout { public static <T> CompletableFuture<T> withTimeout( CompletableFuture<T> future, long timeout, TimeUnit unit, ScheduledExecutorService scheduler) { CompletableFuture<T> timeoutFuture = new CompletableFuture<>(); scheduler.schedule(() -> timeoutFuture.completeExceptionally(new TimeoutException()), timeout, unit ); return future.applyToEither(timeoutFuture, Function.identity()); } } // 使用示例 CompletableFuture<String> original = supplyAsync(() -> longRunningTask()); CompletableFuture<String> protected = withTimeout(original, 3, SECONDS, timeoutPool); ``` --- ### 关键注意事项 1. **线程池管理**: - 使用 `ThreadPoolExecutor` 替代 `Executors` 以便精细控制 ```java ThreadPoolExecutor executor = new ThreadPoolExecutor( 4, 10, 60, SECONDS, new ArrayBlockingQueue<>(100) ); ``` 2. **资源泄漏防护**: ```java try (ExecutorService pool = new ThreadPoolExecutor(...)) { supplyAsync(() -> task(), pool); } // 自动关闭 ``` 3. **异常处理**: ```java future.exceptionally(ex -> { if (ex instanceof TimeoutException) { // 处理超时 } return recoveryAction(); }); ``` 4. **JDK 8 限制**: - 无法直接中断 `supplyAsync()` 中的线程(仅标记中断状态) - 需在任务代码中手动检查中断状态: ```java supplyAsync(() -> { while (!Thread.currentThread().isInterrupted()) { // 工作逻辑 } return "Interrupted"; }); ``` > **超时原理**:通过 `ScheduledExecutorService.schedule()` 在指定延迟后触发超时异常[^2],利用 `applyToEither()` 实现结果竞争机制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值