LockSupport中的park()与unpark()
类注释原文:Basic thread blocking primitives for creating locks and other synchronization classes.
意思就是LockSupport类用于创建锁和其他同步类的基本线程阻塞原语。
LockSupport是基于Unsafe实现的提供的两个主要方法就是park()和unpark()。
其中park()方法我们可以理解为阻塞,等待,挂起,而unpark()我们理解为唤醒,恢复。
park()方法和unpark()方法解释。
LockSupport是其他同步类的及基本线程阻塞原语,所以并不需要获取对象的监视器,而是给线程一个“许可”(permit)。而每个线程的permit只能是0个或者1个。
unpark会给线程一个permit,而且最多是1;而park会消耗一个permit并返回,如果线程没有permit则会阻塞。(默认情况下permit的数量为0,也就是如果直接调用park方法的话,会被直接阻塞的。)
下面我们将对照着源码注释和代码示例对比一下我们的理解是否正确。
park()
原文注释:
/**
* Disables the current thread for thread scheduling purposes unless the
* permit is available.
*
* <p>If the permit is available then it is consumed and the call
* returns immediately; otherwise the current thread becomes disabled
* for thread scheduling purposes and lies dormant until one of three
* things happens:
*
* <ul>
*
* <li>Some other thread invokes {@link #unpark unpark} with the
* current thread as the target; or
*
* <li>Some other thread {@linkplain Thread#interrupt interrupts}
* the current thread; or
*
* <li>The call spuriously (that is, for no reason) returns.
* </ul>
*
*/
上面是park()方法的注释,什么意思呢?
意思就是除非线程允许,否则禁用当前线程以进行线程调度。如果有许可(permit)的话,则将其消耗掉,并且立即返回;否则,出于线程调度的目的,当前线程将被禁用并处于休眠状态,
直到发生以下三种情况之一:
(1):其他线程将当前线程作为目标调用unpark方法;
(2):其他线程interrupt interrupts中断当前线程;
(3):调用无条件返回
unpark(Thread thread)
* Makes available the permit for the given thread, if it
* was not already available. If the thread was blocked on
* {@code park} then it will unblock. Otherwise, its next call
* to {@code park} is guaranteed not to block. This operation
* is not guaranteed to have any effect at all if the given
* thread has not been started.
如果thread线程不可用,则使该线程可用并给他一个许可(permit),。
如果thread线程在被阻止,则它将取消阻止。否则,将确保其对下一次调用park()不会阻塞。
如果给定线程尚未启动,则此操作根本无法保证会产生任何效果。
下面我们就用代码测试一下上面的结论:
(1)直接调用park()会被阻塞
public class TestLockSupport {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(()->{
System.out.println("进入" + Thread.currentThread().getName());
LockSupport.park();
System.out.println(Thread.currentThread().getName()+":"+"block");
LockSupport.park();
System.out.println(Thread.currentThread().getName()+":"+"unblock");
},"线程1");
t1.start();
}
}

只执行了 System.out.println("进入" + Thread.currentThread().getName());说明后面的被阻塞了。
(2)直接调用unpark()会解除阻塞
public class TestLockSupport {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(()->{
System.out.println("进入" + Thread.currentThread().getName());
LockSupport.park();
System.out.println(Thread.currentThread().getName()+":"+"block");
LockSupport.park();
System.out.println(Thread.currentThread().getName()+":"+"unblock");
},"线程1");
t1.start();
LockSupport.unpark(t1);
Thread.sleep(1000);
LockSupport.unpark(t1);
}
}

三次输出都执行了,说明unpark()起作用了。
(3)每个线程最多有一个permit
public class TestLockSupport {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(()->{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("进入" + Thread.currentThread().getName());
LockSupport.park();
System.out.println(Thread.currentThread().getName()+":"+"block");
LockSupport.park();
System.out.println(Thread.currentThread().getName()+":"+"unblock");
},"线程1");
t1.start();
LockSupport.unpark(t1);
LockSupport.unpark(t1);
LockSupport.unpark(t1);
LockSupport.unpark(t1);
LockSupport.unpark(t1);
}
}

在线程t1执行LockSupport.park();之前多次执行了 LockSupport.unpark(t1);,但是最后 System.out.println(Thread.currentThread().getName()+":"+"unblock");没有执行,说明permit的数量只有一个。
LockSupport中的park()与unpark()的更多相关文章
- LockSupport的park和unpark
LockSupport是JDK中比较底层的类,用来创建锁和其他同步工具类的基本线程阻塞原语. Java锁和同步器框架的核心AQS:AbstractQueuedSynchronizer,就是通过调用Lo ...
- 温故知新-多线程-深入刨析park、unpark
文章目录 摘要 park.unpark 看一下hotspot实现 参考 你的鼓励也是我创作的动力 Posted by 微博@Yangsc_o 原创文章,版权声明:自由转载-非商用-非衍生-保持署名 | ...
- park和unpark
1 介绍 LockSupport类是Java6(JSR166-JUC)引入的一个类,提供了基本的线程同步原语.LockSupport提供的两个主要方法就是park和unpark. park译为&quo ...
- LockSupport的park和unpark的基本使用,以及对线程中断的响应性
LockSupport是JDK中比较底层的类,用来创建锁和其他同步工具类的基本线程阻塞原语.java锁和同步器框架的核心AQS:AbstractQueuedSynchronizer,就是通过调用Loc ...
- LockSupport HotSpot里park/unpark的实现
每个java线程都有一个Parker实例,Parker类是这样定义的: class Parker : public os::PlatformParker { private: volatile int ...
- 转:php park、unpark、ord 函数使用方法(二进制流接口应用实例)
在工作中,我也逐渐了解到park,unpark,ord对于二进制字节处理的强大. 下面我逐一介绍它们. park,unpark,ord这3个函数,在我们工作中,用到它们的估计不多. 我在最近一 ...
- park、unpark、ord 函数使用方法(转)
park,unpark,ord这3个函数,在我们工作中,用到它们的估计不多. 我在最近一个工作中,因为通讯需要用到二进制流,然后接口用php接收.当时在处理时候,查阅不少资料.因为它们使用确实比较少, ...
- Linux 进程中 Stop, Park, Freeze【转】
转自:https://blog.csdn.net/yiyeguzhou100/article/details/53134743 http://kernel.meizu.com/linux-proces ...
- 详解Java多线程编程中LockSupport
LockSupport是用来创建锁和其他同步类的基本线程阻塞原语. LockSupport中的park() 和 unpark() 的作用分别是阻塞线程和解除阻塞线程,而且park()和unpark() ...
随机推荐
- Spring Cloud Gateway + Nacos(1)简单配置
当初我学习时候就是参考这位大佬的博客: Nacos集成Spring Cloud Gateway 基础使用 现在学习到spring cloud alibaba 使用nacos做服务中心,dubbo做通信 ...
- pip安装模块或者更新出现问题Error:Could not install packages due to an EnvironmentError
问题分析 出现此问题大致的原因: 就是包安装的位置没有读写的权限,这个多半是因为安装python的时候安装在了C盘,或者其他programs这类的文件夹里 或者就是环境变量的设置的安装位置的问题,导致 ...
- 高阶函数 / abs方法
abs()求绝对值,填括号里面
- 交叉编译参数--build、host和target的区别
build.host和target 在交叉编译中比较 常见 的一些参数就是build.host和target了,正确的理解这三者的含义对于交叉编译是非常重要的,下面就此进行解释 --build=编译该 ...
- Swift系列七 - 汇编分析值类型
通过汇编分下值类型的本质. 一.值类型 值类型赋值给var,let或者给参数传参,是直接将所有内容拷贝一份.类似于对文件进行复制粘贴操作,产生了全新的文件副本,属于深拷贝(deep copy). 示例 ...
- [刷题] 102 Binary Tree Level Order Traversal
要求 对二叉树进行层序遍历 实现 返回结果为双重向量,对应树的每层元素 队列的每个元素是一个pair对,存树节点和其所在的层信息 1 Definition for a binary tree node ...
- 【转载】CentOS下查看电脑硬件设备属性命令
CentOS下查看电脑硬件设备属性命令2018年09月13日 17:48:31 乔烨 阅读数 510如何在linux下查看电脑硬件设备属性 # uname -a # 查看内核/操作系统/CPU信息 # ...
- 实例:使用playbook实现httpd安装、配置、以及虚拟主机的配置
一.安装环境配置 1.在控制节点给受控主机配置本地仓库文件 [root@ansible ~]# vim /etc/yum.repos.d/dvd.repo [AppStream] name=appst ...
- kubernetes 监控(14)
一.Weave Scope 容器地图 创建 Kubernetes 集群并部署容器化应用只是第一步.一旦集群运行起来,我们需要确保一切正常,所有必要组件就位并各司其职,有足够的资源满足应用的需求.Kub ...
- shell应用之cobbler批量部署
如果使用的是原始源,可直接使用该脚本,如果是用的其它源且有cobbler安装包的可删除脚本中的配置yum源步骤.批量部署使用的软件有:cobbler dhcp httpd tftp-server xi ...