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

Java-LockSupport的更多相关文章

  1. 并行编程条件变量(posix condition variables)

    在整理Java LockSupport.park()东方的,我看到了"Spurious wakeup",通过重新梳理. 首先,可以在<UNIX级别编程环境>在样本: # ...

  2. 4.锁--并行编程之条件变量(posix condition variables)

    在整理Java LockSupport.park()的东东.看到了个"Spurious wakeup".又一次梳理下. 首先来个<UNIX环境高级编程>里的样例: [c ...

  3. Spark案例分析

    一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...

  4. 【Java并发编程实战】----- AQS(三):阻塞、唤醒:LockSupport

    在上篇博客([Java并发编程实战]----- AQS(二):获取锁.释放锁)中提到,当一个线程加入到CLH队列中时,如果不是头节点是需要判断该节点是否需要挂起:在释放锁后,需要唤醒该线程的继任节点 ...

  5. Java多线程系列--“JUC锁”07之 LockSupport

    概述 本章介绍JUC(java.util.concurrent)包中的LockSupport.内容包括:LockSupport介绍LockSupport函数列表LockSupport参考代码(基于JD ...

  6. Java并发包源码学习之AQS框架(三)LockSupport和interrupt

    接着上一篇文章今天我们来介绍下LockSupport和Java中线程的中断(interrupt). 其实除了LockSupport,Java之初就有Object对象的wait和notify方法可以实现 ...

  7. Java多线程 LockSupport

    在AQS里面进行阻塞线程,解除阻塞线程就用的LockSupport. JDK1.8源码: package java.util.concurrent.locks; import sun.misc.Uns ...

  8. Java的LockSupport.park()实现分析

    LockSupport类是Java6(JSR166-JUC)引入的一个类,提供了主要的线程同步原语.LockSupport实际上是调用了Unsafe类里的函数,归结到Unsafe里,仅仅有两个函数: ...

  9. 4.锁定--Java的LockSupport.park()实现分析

    LockSupport类是Java6(JSR166-JUC)引入的一个类,提供了主要的线程同步原语. LockSupport实际上是调用了Unsafe类里的函数.归结到Unsafe里,仅仅有两个函数: ...

  10. Java的LockSupport工具,Condition接口和ConditionObject

    在之前我们文章(关于多线程编程基础和同步器),我们就接触到了LockSupport工具和Condition接口,之前使用LockSupport工具来唤醒阻塞的线程,使用Condition接口来实现线程 ...

随机推荐

  1. Linux学习笔记(三)Linux常用命令:链接命令和文件查找命令

    一.链接命令 ln -s [原文件] [目标文件] (link) -s意为创建软连接 硬链接和软连接 硬链接的特点: (1)拥有相同的 i 结点和block块,可以看作是同一个文件 (2)可以通过 i ...

  2. kubernetes之pod调度

    调度规则 deployment全自动调度: 运行在哪个节点上完全由master的scheduler经过一系列的算法计算得出, 用户无法进行干预 nodeselector定向调度: 指定pod调度到一些 ...

  3. tigervnc-server安装

    #vncserver安装方法 #su - root rpm -ivh tigervnc-server-1.8.0-13.el7.x86_64.rpm cp /lib/systemd/system/vn ...

  4. Python Flask学习笔记(1)

    1.搭建虚拟环境 a. 安装 virtualenv : pip3 install virtualenv b. 建立虚拟环境 : 任意目录下建立一个空文件(我的是 Py_WorkSpace) ,在该文件 ...

  5. ActiveMQ部署和代码尝试(二)

    部署和代码尝试 1. 部署在linux 上的acvtiveMQ 要可以通过前台windows 的页面访问,必须把linux 的IP和 windows的 IP 地址配置到同一个网关下 .这种情况一般都是 ...

  6. Java队列与栈转换中String.Valueof()使用

    1. 由 基本数据型态转换成 String String 类别中已经提供了将基本数据型态转换成 String 的 static 方法 也就是 String.valueOf() 这个参数多载的方法 有下 ...

  7. 记一次 解决 vue 兼容ie11 的问题

    vue2.0 最近项目需要做到兼容ie11,找问题找半天,于是各种百度, 发现引入 babel-polyfill 还是有问题  空白页面 参考它的配置 ( 最后一句代码为引入的资源路径 )  我跟他差 ...

  8. codeblock的一个小问题

    也许不叫问题吧,也可能是编译器的特性. 我的codeblock选择的编译器: 编写.cpp文件时,floatl类型输入输出都是 %f,double类型输入只能是 %lf,输出只能是 %f. 但是在co ...

  9. [2019HDU多校第一场][HDU 6590][M. Code]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6590 题目大意(来自队友):二维平面上有\(n\)个点,每个点要么是黑色要么是白色,问能否找到一条直线 ...

  10. Python基础--基于ubuntu linux基础知识点

    part1:Python编译 1.直接在终端编译-----在ubuntu中Python是在home文件夹下的,输入Python(Python2编译,想要Python3直接输入python3) 一般推荐 ...