zoukankan      html  css  js  c++  java
  • Java-LockSupport

    LockSupport 和 CAS 是 Java 并发包中很多并发工具控制机制的基础,它们底层其实都是依赖 Unsafe 实现。

    LockSupport 提供 park() 和 unpark() 方法实现阻塞线程和解除线程阻塞。

    每个使用 LockSupport 的线程都会与一个许可(permit)关联,如果该许可可用,则调用 park() 将会立即返回。如果许可尚不可用,则可以调用 unpark() 使其可用,否则可能阻塞。

    permit 最多只有一个,重复调用 unpark() 也不会累加。unpark() 可以先于 park() 调用。

    每个 Java 线程都有一个 Parker 实例:http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/760b28d87178/src/share/vm/runtime/park.hpp,在 Parker 类里的 _counter 字段,就是用来记录所谓的“许可”的。

    一、API

    阻塞

    • void park():阻塞当前线程,如果调用 unpark() 方法或者当前线程被中断,从能从 park() 方法中返回
    • void park(Object blocker):功能同方法上,入参增加一个 Object 对象,用来记录导致线程阻塞的阻塞对象,方便 dump 线程时进行问题排查
    • void parkNanos(long nanos):阻塞当前线程,最长不超过 nanos 纳秒,增加了超时返回的特性
    • void parkNanos(Object blocker, long nanos):功能同方法上,入参增加一个 Object 对象,用来记录导致线程阻塞的阻塞对象,方便 dump 线程时进行问题排查
    • void parkUntil(long deadline):阻塞当前线程,直到 deadline
    • void parkUntil(Object blocker, long deadline):功能同方法上,入参增加一个 Object 对象,用来记录导致线程阻塞的阻塞对象,方便 dump 线程时进行问题排查

    唤醒

    • void unpark(Thread thread):唤醒处于阻塞状态的指定线程

    二、使用

    1.先 park 再 unpark

    Thread t = new Thread(() -> {
        System.out.println("睡觉");
        LockSupport.park();
        System.out.println("起床");
    });
    t.start();
    Thread.sleep(1000);
    System.out.println("妈妈喊我起床");
    LockSupport.unpark(t);

     2.先 interrupt 再 park

    Thread t = new Thread(() -> {
        System.out.println("睡觉");
        LockSupport.park();
        System.out.println("起床");
        System.out.println("是否中断:" + Thread.currentThread().isInterrupted());
    });
    t.start();
    t.interrupt();
    System.out.println("突然肚子很疼");

    可以看到中断后执行 park() 会直接执行下面的方法,并不会抛出 InterruptedException

     3.先 unpark 再 park

    Thread t = new Thread(() -> {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("睡觉");
        LockSupport.park();
        System.out.println("7点到,起床");
    });
    t.start();
    LockSupport.unpark(t);
    System.out.println("提前上好闹钟7点起床");

     先设置好许可(unpark)再获取许可的时候不会进行等待


    https://benjaminwhx.com/2018/05/01/%E3%80%90%E7%BB%86%E8%B0%88Java%E5%B9%B6%E5%8F%91%E3%80%91%E8%B0%88%E8%B0%88LockSupport/

    https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/LockSupport.html

  • 相关阅读:
    求24点
    关于参数和返回值的常量性
    点到平面的距离公式
    大端序与小端序
    Quake3中的绝对值函数
    整数超出范围时如何表示?
    关于数组的几道面试题
    在移位数组中查找数
    时间复杂度O(n),空间复杂度O(1)的排序
    C++之对象切割
  • 原文地址:https://www.cnblogs.com/jhxxb/p/11527735.html
Copyright © 2011-2022 走看看