java线程阻塞中断与LockSupport使用介绍


在Java中,线程阻塞和中断是并发编程中的核心概念,而`LockSupport`是一个实用的工具类,它提供了基本的线程阻塞和唤醒功能。下面是对线程阻塞中断和`LockSupport`使用的简要介绍。

### 线程阻塞中断

在Java中,当线程执行到某些阻塞操作(如等待锁、等待某个条件成立等)时,它可能会处于阻塞状态。此时,如果希望中断这个线程的执行,可以通过调用该线程的`interrupt()`方法来实现。然而,仅仅调用`interrupt()`并不足以使阻塞的线程立即退出阻塞状态。

线程需要定期检查中断状态(通过调用`Thread.interrupted()`或`Thread.currentThread().isInterrupted()`),并在检测到中断时适当地处理(通常是清理资源并退出)。但是,对于某些阻塞操作(如`Object.wait()`, `Thread.join()`, `Thread.sleep()`等),这些操作本身会响应中断,即在中断发生时抛出`InterruptedException`。

### LockSupport使用

`LockSupport`是Java并发包`java.util.concurrent.locks`中的一个工具类,它提供了一种灵活的线程阻塞和唤醒机制。与`Object`的`wait()`/`notify()`/`notifyAll()`机制相比,`LockSupport`更加灵活,并且不依赖于同步锁。

#### 主要方法

- `static void park()`:阻塞当前线程,直到它被另一个线程唤醒。

- `static void parkNanos(long nanos)`:阻塞当前线程,但不超过指定的纳秒数。

- `static void parkUntil(long deadline)`:阻塞当前线程,直到指定的绝对时间。

- `static void unpark(Thread thread)`:唤醒在`park()`、`parkNanos()`或`parkUntil()`中阻塞的指定线程(如果它尚未被唤醒)。

#### 使用示例


// 线程T1
Thread t1 = new Thread(() -> {
    System.out.println("Thread 1 is going to park");
    LockSupport.park(); // 阻塞线程
    System.out.println("Thread 1 is unparked");
});

t1.start();

// 主线程或其他线程
Thread.sleep(1000); // 假设我们想让t1先运行并阻塞

System.out.println("Unparking thread 1");
LockSupport.unpark(t1); // 唤醒t1

在这个示例中,线程`t1`执行到`LockSupport.park()`时会被阻塞。随后,在主线程中调用`LockSupport.unpark(t1)`来唤醒`t1`。注意,`unpark`调用可以发生在`park`调用之前,线程`t1`仍会在`park`处阻塞,直到`unpark`调用发生。此外,`unpark`调用可以多次对同一个线程进行,但额外的`unpark`调用会被忽略。