美文网首页工作生活
J.U.C之LockSupport:线程等待和唤醒

J.U.C之LockSupport:线程等待和唤醒

作者: 贪睡的企鹅 | 来源:发表于2019-07-03 13:21 被阅读0次

1 LockSupport 概述

LockSupprot是线程的阻塞原语,用来阻塞线程和唤醒线程。每个使用LockSupport的线程都会与一个许可关联,如果该许可可用,并且可在线程中使用,则调用park()将会立即返回,否则可能阻塞。如果许可尚不可用,则可以调用 unpark 使其可用。但是注意许可不可重入,也就是说只能调用一次park()方法,否则会一直阻塞。

2 LockSupport API

获取许可相关

//获取许可,如果成功则直接返回,失败则一直阻塞当前线程。
//直到系统调用unpark方法或者当前线程被中断时可以从阻塞中唤醒从park()方法中返回
public static void park() {
        UNSAFE.park(false, 0L);
}

//功能同park()方法,增加了一个Object对象参数,用来记录导致线程阻塞的阻塞对象,方便进行问题排查;
public static void park(Object blocker) {
    Thread t = Thread.currentThread();
    setBlocker(t, blocker);
    UNSAFE.park(false, 0L);
    setBlocker(t, null);
}

//功能同park()方法,增加了一个超时时间nanos(纳秒),如果线程获取许可失败,阻塞不再是永久,而时增加了超时返回的特性;
public static void parkNanos(long nanos) {
        if (nanos > 0)
            UNSAFE.park(false, nanos);
}

//功能同parkNanos,增加了一个Object对象参数,用来记录导致线程阻塞的阻塞对象,方便进行问题排查;
public static void parkNanos(long nanos) {
    if (nanos > 0)
        UNSAFE.park(false, nanos);
}

//功能同park()方法,这里超时时间变成了绝对的超时时间,超时时间单位变成纳秒。
public static void parkUntil(long deadline) {
    UNSAFE.park(true, deadline);
}

//功能同parkUntil,增加了一个Object对象参数,用来记录导致线程阻塞的阻塞对象,方便进行问题排查;    
public static void parkUntil(Object blocker, long deadline) {
    Thread t = Thread.currentThread();
    setBlocker(t, blocker);
    UNSAFE.park(true, deadline);
    setBlocker(t, null);
}    

释放许可

     //释放一个线程的许可。如果线程在等待许可阻塞,会被唤醒。
     public static void unpark(Thread thread) {
        if (thread != null)
            UNSAFE.unpark(thread);
    }

线程dump

UNSAFE

LockSupport 实现上通过UNSAFE实现。特性上和UNSAFE相同,我们来回顾下UNSAFE 特性:

  • 默认情况下线程中不存在许可。当前线程第一次使用Unsafe 调用park方法时(如果未调用unpark)会导致当前线程阻塞。

  • 同一个线程多次归还许可只和一次归还相同

  • unpark 无法恢复处于 sleep 中的线程,只能与 park 配对使用,因为 unpark 发放的许可只有 park 能监听到。

使用例子

package locksupport;

import org.junit.Test;

import java.util.concurrent.locks.LockSupport;

public class LockSupportTest {

    @Test
    public void park1(){
        LockSupport.park();
    }

    @Test
    public void park2(){
        long star=System.currentTimeMillis();
        LockSupport.parkNanos(5000000000L);
        System.out.println(System.currentTimeMillis()-star);
    }


    @Test
    public void park3(){
        long star=System.currentTimeMillis();
        LockSupport.parkUntil(System.currentTimeMillis()+5000L);
        System.out.println(System.currentTimeMillis()-star);
    }



    @Test
    public void park5() {
        Thread currThread = Thread.currentThread();
        LockSupport.unpark(currThread);
        LockSupport.unpark(currThread);
        LockSupport.unpark(currThread);
        LockSupport.park();
        LockSupport.park();
        System.out.println("execute success"); // 线程挂起,不会打印。
    }
}

相关文章

  • J.U.C之LockSupport:线程等待和唤醒

    1 LockSupport 概述 LockSupprot是线程的阻塞原语,用来阻塞线程和唤醒线程。每个使用Lock...

  • LockSupport实现原理

    前文中了解到AQS借助LockSupport.park和LockSupport.unpark完成线程的阻塞和唤醒,...

  • LockSupport 介绍

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

  • 优雅循环打印abc的方法

    调用locksupport 可以 指定唤醒哪个线程特性优雅实现线程循环打印

  • JUC锁框架_ LockSupport原理分析

    一. LockSupport类介绍 LockSupport类可以阻塞当前线程以及唤醒指定被阻塞的线程。主要是通过p...

  • AQS中的Condtion和LockSupport的关系

    LockSupport可以对指定线程阻塞,唤醒,不需要监听器。 Condtion也能对当前线程进行阻塞和唤醒,但功...

  • LockSupport

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

  • FutureTask 源码学习

    FutureTask主要利用 LockSupport 实现阻塞和唤醒 WaitNode 只是简单保存了一个线程和 ...

  • java并发编程之LockSupport

    LockSupport,构建同步组件的基础工具,帮AQS完成相应线程的阻塞或者唤醒的工作。 LockSupport...

  • LockSupport

    LockSupport是juc提供的同步组件,用来阻塞和唤醒线程。Basic thread blocking pr...

网友评论

    本文标题:J.U.C之LockSupport:线程等待和唤醒

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