• LockSupport


    1.概念

    LockSupport是用来进行线程的通信的,是一个线程阻塞的工具类,其中里面的方法都是静态方法,park()和unpark()的作用分别是阻塞线程和唤醒线程。

    2.线程等待和唤醒机制

    • 方式一:使用Object中的wait()方法让线程等待,使用Object中的notify()方法唤醒线程

    • 方式二:使用JUC包中的Condition的await()方法让线程等待,使用signal()方法唤醒线程

    • 方式三:LockSupport类可以阻塞当前线程以及唤醒指定被阻塞的线程

    方式一必须在同步代码块或者同步方法中成对使用,先wait后notify才能正常使用。

    方式二必须先获取锁后才能使用,并且是先await后signal才能正常使用。

    3.LockSupport的强大之处

    LockSupport类中使用了一种名为Permit(许可证)的概念来实现阻塞和唤醒线程的功能,而且许可证只能有一个,不能累加

    park:许可证默认没有所以会阻塞,等到发放许可才能唤醒。

    unpark:发放许可证,自动唤醒等待的线程。

    1. public class LockSupportDemo {
    2. public static void main(String[] args) {
    3. Thread t1 = new Thread(() -> {
    4. System.out.println(Thread.currentThread().getName() + "\t -----------come in");
    5. LockSupport.park(); //阻塞
    6. System.out.println(Thread.currentThread().getName() + "\t ----------被唤醒");
    7. }, "t1");
    8. t1.start();
    9. try {
    10. TimeUnit.SECONDS.sleep(1);
    11. } catch (InterruptedException e) {
    12. e.printStackTrace();
    13. }
    14. new Thread(() -> {
    15. LockSupport.unpark(t1);//发放许可
    16. System.out.println(Thread.currentThread().getName() + "\t ----------发出通知");
    17. }, "t2").start();
    18. }
    19. }

    形象的理解:线程阻塞时需要消耗凭证,这个凭证最多只有一个,当调用park时,如果有许可,那么就直接消耗,继续向下进行,如果没有,则阻塞等待许可证的发放。当调用unpark时,发放一个许可证,多次调用不会累加。

    4.面试高频题

    4.1为什么LockSupport可以突破wait/notify的原有调用顺序?

    因为unpark获得了一个凭证,之后再调用park方法,就可以名正言顺的凭证消费,故不会阻塞,先发放了凭证后续可以畅通无阻。

    4.2为什么连续调用两次unpark方法,再调用两次park方法,还是会阻塞?

    因为凭证的数量最大为1,而调用两次park方法却需要两个许可,证不够,所以会阻塞。

     

  • 相关阅读:
    linux文件锁的使用
    HTML学生个人网站作业设计成品 HTML+CSS肖战明星人物介绍网页 web结课作业的源码
    字符串的创建及常用方法大全
    Java的基础语法(三)
    【Linux】软件管理器yum和编辑器vim
    抢先体验! 在浏览器里写 Flutter 是一种什么体验?
    MyBatis
    全链路业务追踪落地实践方案
    QT QToolBox控件使用详解
    Redis实战——优惠券秒杀(超卖问题)
  • 原文地址:https://blog.csdn.net/m0_62565675/article/details/133427346