LockSupport与线程中断

简介: LockSupport与线程中断

LockSupport是JDK提供的一种基本的线程同步原语,它可以实现线程的阻塞和唤醒,比synchronized更为灵活,且可以指定唤醒的线程。本文主要介绍LockSupport的用法及其与线程中断的关系。

LockSupport简介

LockSupport是由Doug Lea等人在Java 1.6中引入的一种线程同步工具,它可以阻塞和唤醒线程,并且不需要使用任何锁。它是Java中最基本的线程同步原语之一,也是实现Lock和其他锁的基础。LockSupport通过让线程等待许可证而阻塞线程,许可证可以被其他线程释放。如果许可证在没有发放给线程的情况下被请求,那么该线程将一直阻塞。

LockSupport的API包括以下方法:

public static void park();
public static void park(Object blocker);
public static void unpark(Thread thread);

park()方法用于阻塞当前线程,直到unpark()被调用或中断事件发生。如果线程在调用park()之前被中断,那么它会立即返回。

park(Object blocker)方法可以阻塞当前线程,并将阻塞对象blocker传递给LockSupport,以便于诊断和调试。

unpark(Thread thread)方法则可以唤醒特定的线程,如果线程在调用unpark()之前已经被阻塞,那么它会立即返回。

LockSupport使用示例

下面是一个简单的示例,演示了如何使用LockSupport对线程进行阻塞和唤醒:

public class LockSupportDemo {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            System.out.println("线程1开始执行");
            // 调用park()方法阻塞线程1
            LockSupport.park();
            System.out.println("线程1被唤醒");
        });
        t1.start();
        Thread.sleep(2000);
        Thread t2 = new Thread(() -> {
            System.out.println("线程2开始执行");
            // 唤醒线程1
            LockSupport.unpark(t1);
        });
        t2.start();
    }
}

在这个示例中,我们创建了两个线程t1和t2,其中t1会在执行到LockSupport.park()时被阻塞,直到t2调用LockSupport.unpark(t1)唤醒t1,t1才会继续执行。

LockSupport与线程中断

在Java中,线程中断是一种常用的线程协作机制,它可以在任何时候打断一个正在运行的线程,通过抛出InterruptedException异常来通知该线程被中断了。对于被阻塞的线程,如果它正在等待一个锁或者调用了Thread.sleep()等方法,那么它会立即被中断并抛出InterruptedException异常。但是对于正在执行CPU密集型任务的线程,中断信号并不能立即被响应,可能需要等待一段时间才能被响应。

LockSupport与线程中断的关系在于,如果一个线程在调用park()方法阻塞之前被中断,那么会立即返回,不会发生阻塞。而如果一个线程在调用park()方法阻塞之后被中断,那么它需要检查中断标志位并自行处理中断事件。

我们可以通过Thread.interrupted()方法来检查当前线程是否被中断,如果被中断,则需要处理中断事件。下面是一个示例:

public class LockSupportInterruptDemo {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            System.out.println("线程1开始执行");
            // 调用park()方法阻塞线程1
            LockSupport.park();
            System.out.println("线程1被唤醒");
            if (Thread.interrupted()) {
                // 处理中断事件
                System.out.println("线程1被中断了");
            }
        });
        t1.start();
        Thread.sleep(2000);
        Thread t2 = new Thread(() -> {
            System.out.println("线程2开始执行");
            // 中断线程1
            t1.interrupt();
            // 唤醒线程1
            LockSupport.unpark(t1);
        });
        t2.start();
    }
}

在这个示例中,我们在t2中断t1之后,调用了LockSupport.unpark(t1)方法唤醒了t1,同时在t1被唤醒之后,使用Thread.interrupted()方法检查当前线程是否被中断,如果被中断,则处理中断事件。

需要注意的是,如果在调用park()方法时已经被中断,那么LockSupport.park()方法不会阻塞,会立即返回。因此,在检查中断标志位之前,需要先调用Thread.interrupted()方法来清除中断标志位,否则后面的代码可能会误判当前线程是否被中断。

总结

LockSupport是Java中最基本的线程同步原语之一,它可以实现线程的阻塞和唤醒,比synchronized更为灵活。LockSupport与线程中断的关系在于,如果一个线程在调用park()方法阻塞之前被中断,那么会立即返回,不会发生阻塞。而如果一个线程在调用park()方法阻塞之后被中断,那么它需要检查中断标志位并自行处理中断事件。在使用LockSupport时需要注意检查中断标志位,以及清除中断标志位。


相关文章
|
10月前
一文解读LockSupport
一文解读LockSupport
|
10月前
|
Java 程序员
JUC之线程中断机制解读(interrupt)
JUC之线程中断机制解读(interrupt)
|
5月前
线程中断方法详解interrupt
线程中断方法详解interrupt
39 0
|
7月前
|
Java 开发者
停止线程 & 守护线程 & 线程阻塞
停止线程 & 守护线程 & 线程阻塞
9 0
停止线程 & 守护线程 & 线程阻塞
|
10月前
|
算法 Java 调度
线程的挂起和唤醒
线程的挂起和唤醒
|
Java
线程中断方法interrupt、isInterrupted、interrupted方法
线程中断方法interrupt、isInterrupted、interrupted方法
87 0
线程中断方法interrupt、isInterrupted、interrupted方法
|
Java 程序员 API
JUC - 线程中断与线程等待、唤醒(LockSupport)
JUC - 线程中断与线程等待、唤醒(LockSupport)
JUC - 线程中断与线程等待、唤醒(LockSupport)
|
Java 数据安全/隐私保护
【线程】用 CyclicBarrier 实现线程同步
在玩游戏的时候我们经常遇到,我的进度条已经到了100%,但是却一直进不了游戏,这就是因为需要相互等待,等所有人准备完毕,才能开始。
【JavaSE】多线程篇(二)线程终止、线程中断与线程插队
文章目录 1 线程终止 2 线程常用方法 2.1 常用方法一览表 2.2 方法注意事项 3 线程中断 4 线程插队 写在最后
【JavaSE】多线程篇(二)线程终止、线程中断与线程插队
|
Java 开发者
线程中断|学习笔记
快速学习线程中断
线程中断|学习笔记