美文网首页
并发包中的LockSupport工具类

并发包中的LockSupport工具类

作者: nieniemin | 来源:发表于2021-09-05 10:22 被阅读0次

一、 LockSupport简介

LockSupport类是一个Java6(JSR166-JUC)引入的一个工具类,它的主要作用是对线程进行挂起和唤醒,它是创建锁和其他同步类的基础。

LockSupport类的核心方法其实就两个:park()和unpark(),其中park()方法用来阻塞当前调用线程,unpark()方法用于唤醒指定线程。这和Object的wait/notify、Condition的await/signal、以及Semaphore的acquire/release功能类似。
但是LockSupport的这两种方法从语意上讲比Object类的方法更清晰,而且可以针对指定线程进行阻塞和唤醒
注意:park方法真正的实现是Unsafe类

private static final sun.misc.Unsafe UNSAFE;
public static void park() {
        UNSAFE.park(false, 0L);
}

LockSupport类使用了一种名为Permit(许可)的概念来做到阻塞和唤醒线程的功能,可以把许可看成是一种(0,1)信号量(Semaphore),但与 Semaphore 不同的是,许可的累加上限是1。
初始时,permit为0,当调用unpark()方法时,线程的permit加1,当调用park()方法时,如果permit为0,则调用线程进入阻塞状态。

二、 LockSupport API

Park方法:

如果调用LockSupport.park()方法的线程已经拿到了与LockSupport关联的许可证,则调用时会马上返回,否则调用线程会被禁止参与线程的调度,也就是会被阻塞挂起。

public class LockSupportMain {
    public static void main(String[] args) {
        System.out.println("main线程----------park前");
   //直接在main函数中调用park()方法,当前线程被挂起。
        //在默认情况下,调用线程是不持有许可证的。
        LockSupport.park();
        System.out.println("main线程----------park后");
    }
}
****************************只会输出调用park()方法前内容*******
main线程----------park前

unPark(Thread thread):

当一个线程调用LockSupport.unpark()方法时,如果参数thread线程没有持有thread与LockSupport类关联的许可证,则让thread线程持有;

而如果thread之前因调用LockSupport.park()方法时被挂起,则调用LockSupport.unpark()方法后,该线程会被唤醒。

而如果thread之前没有调用LockSupport.park()方法,则调用LockSupport.unpark()方法后,再调用LockSupport.park()方法,其会立刻返回。

public class LockSupportMain {
    public static void main(String[] args) {
        System.out.println("main线程----------park前");
        //使用当前线程获取到许可证
        LockSupport.unpark(Thread.currentThread());
        LockSupport.park();
        System.out.println("main线程----------park后");
    }
}
*******************************************
main线程----------park前
main线程----------park后
public class LockSupportMain {
    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            System.out.println("子线程开始...");
            //调用LockSupport.park()方法,挂起自己
            //默认情况下,子线程没有持有许可证,因而它会把自己挂起。
            LockSupport.park();
            System.out.println("调用park后,改行不会打印,直到LockSupport.unpark(thread)唤醒后,
才会打印这行,子线程才会结束.");

        });
        thread.start();

        try {
            Thread.sleep(10_000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //10s后,main线程调用LockSupport.unpark()方法让thread线程持有许可证,
        //然后LockSupport.park()方法返回。
        LockSupport.unpark(thread);
    }
}

LockSupport的使用过程中还需要注意以下几点:

  • 和wait方法一样,park方法也需要在循环体中使用。这是为了防止线程被唤醒后,不进行判断而意外继续向下执行。
  • park方法是会响应中断的,但是不会抛出异常。(也就是说如果当前调用线程被中断,则会立即返回但不会抛出中断异常)
  • park的重载方法park(Object blocker),会传入一个blocker对象,所谓Blocker对象,其实就是当前线程调用时所在调用对象(如上述示例中的FIFOMutex对象)。该对象一般供监视、诊断工具确定线程受阻塞的原因时使用。

相关文章

  • 并发包中的LockSupport工具类

    一、 LockSupport简介 LockSupport类是一个Java6(JSR166-JUC)引入的一个工具类...

  • 并发编程05--Java中的锁(LockSupport工具和Co

    Java中的锁 LockSupport工具 当需要阻塞或唤醒一个线程的时候,都会使用LockSupport工具类来...

  • 【细谈Java并发】谈谈LockSupport

    1、简介 LockSupport 和 CAS 是Java并发包中很多并发工具控制机制的基础,它们底层其实都是依赖U...

  • java初入多线程10

    线程阻塞工具类 :LockSupport LockSupport 是一个非常实用的线程阻塞工具, 可以在线程内任意...

  • LockSupport 介绍

    LockSupport 的功能 LockSupport 是JDK 中提供的一个工具类,用来挂起和唤醒线程,这个类是...

  • Java CAS

    CAS和LockSupport可以说贯穿了java并发包(自旋锁 + CAS + LockSupport + 内存...

  • java并发包底层原理

    前言 JDK并发包是基于两个基础类 Unsafe 和 LockSupport实现的: unsafe 提供基于os系...

  • 并发编程-(3)-LockSupport

    目录: 1、LockSupport工具定位: 2、LockSupport工具定义: 3、LockSupport常用...

  • 用线程顺序打印A1B2C3....Z26

    LockSupport LockSupport是一个线程工具类,所有的方法都是静态方法,可以让线程在任意位置阻塞,...

  • LockSupport

    LockSupport简介 LockSupport用来实现线程的挂起和唤醒,它是Java6引入的一个工具类,它简单...

网友评论

      本文标题:并发包中的LockSupport工具类

      本文链接:https://www.haomeiwen.com/subject/eckjwltx.html