13.LockSupport工具
1. LockSupport简介
在之前介绍AQS的底层实现,已经在介绍java中的Lock时,比如ReentrantLock,ReentReadWriteLocks,已经在介绍线程间等待/通知机制使用的Condition时都会调用LockSupport.park()方法和LockSupport.unpark()方法。而这个在同步组件的实现中被频繁使用的LockSupport到底是何方神圣,现在就来看看。LockSupport位于java.util.concurrent.locks包下,有兴趣的可以直接去看源码,该类的方法并不是很多。LockSupprot是线程的阻塞原语,用来阻塞线程和唤醒线程。每个使用LockSupport的线程都会与一个许可关联,如果该许可可用,并且可在线程中使用,则调用park()将会立即返回,否则可能阻塞。如果许可尚不可用,则可以调用 unpark 使其可用。但是注意许可不可重入,也就是说只能调用一次park()方法,否则会一直阻塞。
2. LockSupport方法介绍
LockSupport中的方法不多,这里将这些方法做一个总结:
阻塞线程
void park():阻塞当前线程,如果调用unpark方法或者当前线程被中断,可以从park()方法中返回(park()后面的方法能被继续执行)
void park(Object blocker):功能同方法1,入参增加一个Object对象,用来记录导致线程阻塞的阻塞对象,方便进行问题排查;
void parkNanos(long nanos):阻塞当前线程,最长不超过nanos纳秒,增加了超时返回的特性;
void parkNanos(Object blocker, long nanos):功能同方法3,入参增加一个Object对象,用来记录导致线程阻塞的阻塞对象,方便进行问题排查;
void parkUntil(long deadline):阻塞当前线程,直到deadline;传入行号
void parkUntil(Object blocker, long deadline):功能同方法5,入参增加一个Object对象,用来记录导致线程阻塞的阻塞对象,方便进行问题排查;
唤醒线程
7.void unpark(Thread thread):唤醒处于阻塞状态的指定线程
实际上LockSupport阻塞和唤醒线程的功能是依赖于sun.misc.Unsafe,这是一个很底层的类,有兴趣的可以去查阅资料,比如park()方法的功能实现则是靠unsafe.park()方法。另外在阻塞线程这一系列方法中还有一个很有意思的现象就是,每个方法都会新增一个带有Object的阻塞对象的重载方法。那么增加了一个Object对象的入参会有什么不同的地方了?示例代码很简单就不说了,直接看dump线程的信息。
调用park()方法dump线程:
"main" #1 prio=5 os_prio=0 tid=0x02cdcc00 nid=0x2b48 waiting on condition [0x00d6f000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:304)
at learn.LockSupportDemo.main(LockSupportDemo.java:7)
调用park(Object blocker)方法dump线程
"main" #1 prio=5 os_prio=0 tid=0x0069cc00 nid=0x6c0 waiting on condition [0x00dcf000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x048c2d18> (a java.lang.String)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at learn.LockSupportDemo.main(LockSupportDemo.java:7)
通过分别调用这两个方法然后dump线程信息可以看出,带Object的park方法相较于无参的park方法会增加 parking to wait for <0x048c2d18> (a java.lang.String)的信息,这种信息就类似于记录“案发现场”,有助于工程人员能够迅速发现问题解决问题。有个有意思的事情是,我们都知道如果使用synchronzed阻塞了线程dump线程时都会有阻塞对象的描述,在java 5推出LockSupport时遗漏了这一点,在java 6时进行了补充。还有一点需要需要的是:synchronzed致使线程阻塞,线程会进入到BLOCKED状态,而调用LockSupprt方法阻塞线程会致使线程进入到WAITING状态。
3. 一个例子
用一个很简单的例子说说这些方法怎么用。
public class LockSupportDemo {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
LockSupport.park();
System.out.println(Thread.currentThread().getName() + "被唤醒");
});
thread.start();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
LockSupport.unpark(thread);
}
}
thread线程调用LockSupport.park()致使thread阻塞,当mian线程睡眠3秒结束后通过LockSupport.unpark(thread)方法唤醒thread线程,thread线程被唤醒执行后续操作。另外,还有一点值得关注的是,LockSupport.unpark(thread)可以指定线程对象唤醒指定的线程。
13.LockSupport工具的更多相关文章
- Java的LockSupport工具,Condition接口和ConditionObject
在之前我们文章(关于多线程编程基础和同步器),我们就接触到了LockSupport工具和Condition接口,之前使用LockSupport工具来唤醒阻塞的线程,使用Condition接口来实现线程 ...
- Java并发包源码学习系列:挂起与唤醒线程LockSupport工具类
目录 LockSupport概述 park与unpark相关方法 中断演示 blocker的作用 测试无blocker 测试带blocker JDK提供的demo 总结 参考阅读 系列传送门: Jav ...
- java高并发系列 - 第14天:JUC中的LockSupport工具类,必备技能
这是java高并发系列第14篇文章. 本文主要内容: 讲解3种让线程等待和唤醒的方法,每种方法配合具体的示例 介绍LockSupport主要用法 对比3种方式,了解他们之间的区别 LockSuppor ...
- 了解LockSupport工具类
介绍: 在网上也没有找到太多的东西,大概说了一下,这个工具类的所有方法都是静态的,底层采用UNSAFE直接操作的内存,可以实现线程的阻塞和唤醒 可以看到他的park方法调用的是UNSAFE的park方 ...
- java中线程的停止以及LockSupport工具类
看jstack输出的时候,可以发现很多状态都是TIMED_WAITING(parking),如下所示: "http-bio-8080-exec-16" #70 daemon pri ...
- 我的第一个python web开发框架(13)——工具函数包说明(四)
string_helper.py是字符串操作包,主要对字符串进行检查.过滤和截取等处理. #!/usr/bin/evn python # coding=utf-8 import re def chec ...
- Java多线程系列——线程阻塞工具类LockSupport
简述 LockSupport 是一个非常方便实用的线程阻塞工具,它可以在线程内任意位置让线程阻塞. 和 Thread.suspend()相比,它弥补了由于 resume()在前发生,导致线程无法继续执 ...
- java高并发系列 - 第15天:JUC中的Semaphore,最简单的限流工具类,必备技能
这是java高并发系列第15篇文章 Semaphore(信号量)为多线程协作提供了更为强大的控制方法,前面的文章中我们学了synchronized和重入锁ReentrantLock,这2种锁一次都只能 ...
- java高并发系列 - 第16天:JUC中等待多线程完成的工具类CountDownLatch,必备技能
这是java高并发系列第16篇文章. 本篇内容 介绍CountDownLatch及使用场景 提供几个示例介绍CountDownLatch的使用 手写一个并行处理任务的工具类 假如有这样一个需求,当我们 ...
随机推荐
- 如何看MFC程序
一直以来 我都一个疑惑 如果看懂别人的MFC 程序. 今日忽然略有小悟. Q:MFC是啥? A:MFC是类库.. ************* Q :MFC 啥玩意类库? A;MFC 是封装API的类 ...
- linxu系统压缩解压命令
使用cat命令进行文件的纵向合并 两种文件的纵向合并方法 归档文件和归档技术 归档的目的 什么是归档 tar命令的功能 tar命令的常用选项 使用tar命令创建.查看及抽取归档文件 使用tar命令创建 ...
- 在Delphi中使用indy SMTP发送gmail邮件[转]
在Delphi中使用indy SMTP发送gmail邮件[转] 2012-01-01 22:44:30| 分类: Delphi | 标签: |举报 |字号大中小 订阅 在Delphi中发送 ...
- Linux系统——特殊符号、通配符及正则表达式
特殊符号 | 管道符号,将管道符左边的命令的执行结果以字符串的形式通过 管道符传送到管道符右边命令末尾,作为管道符右边命令的执行 范围 > 输出重定向 >> 追加输出重定向 < ...
- Jmeter数据库mysql测试说明
主要分3个步骤,详细操作步骤如下: 一.环境准备 1.下载mysql驱动,下载地址:https://dev.mysql.com/downloads/connector/j/,Select Operat ...
- 对java NIO 通道的一些了解
@引言 reactor(反应器)模式 使用单线程模拟多线程,提高资源利用率和程序的效率,增加系统吞吐量.下面例子比较形象的说明了什么是反应器模式: 一个老板经营一个饭店, 传统模式 - 来一个客人安排 ...
- JS正则表达式从入门到入土(10)—— 字符串对象方法
字符串对象方法 search方法 String.prototype.search(reg) search方法用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串,方法返回第一个匹配结果的 ...
- 学号20145303 《Java程序设计》第一周学习总结
学号20145303 <Java程序设计>第一周学习总结 教材学习内容总结 *dos命令行: dir:列出当前目录下的文件及文件名 md:创建目录 rd:删除目录.为空时文件夹(文件夹为空 ...
- 扒开系统调用的三层皮(下)/给MenuOS增加time和time-asm命令
上周从用户态的角度去理解系统调用 这周通过内核的方式 调试和跟踪系统调用来理解 rm menu -rf 强制删除原menu文件 git clone https://github.com/mengni ...
- mongodb入门很简单(2)
mongodb的安装 1.下载mongodb: www.mongodb.org 下载最新的stable版:我下载的版本是3.2.5 2.解压文件 3.不用编译:本身就是编译后的二进制可执行文件 打开 ...