LockSupport 的理解

本文详细讲解了LockSupport的构造原理、park/unpark方法的作用、许可机制、与Thread.suspend/resume的区别,以及如何避免竞争引发的阻塞。重点介绍了其在高级同步工具中的应用和公园操作的细节,包括时间参数和中断处理。

Locksupport 理解

LockSupport 的构造方法都是私有的。对于创建锁或者其他同步类是基本的线程阻塞原语。
LockSupport 与使用它的线程 以及 permit 关联,如果permit 可用的话,park 函数调用使得会立即返回,并消费掉一个permit,否则线程会阻塞。如果之前permit 不可用的时候 即数量为0 的时候,unpark 会使得permit 再次可用,注意与semaphore不同,permit数量不会累积,其数量最多为1 个。
parkunpark用来阻塞或者恢复线程不会遇到Thread.suspendThread.resume 引发的问题 。Thread.suspendThread.resume对于这样的情况无能为力:一个线程调用park 另一个线程尝试调用unpark 即二者存在某种竞争关系,此时就不应该使用suspend和resume(因为suspend 只是单纯的挂起线程不会释放线程占用的锁,所以其挂起后其他等待他持有的锁的线程不能得到执行,直到其他线程调用Thread.resume 但是 因为存在竞争关系 所以Thread.resume 可能先执行 所以 导致后执行的suspend 一直阻塞 发生死锁)而parkunpark 因为permit 的变量的引入,即使先调用unparkpermit 在不可用 即数量为0 的情况下 会变为1.使得park 会立即消费permit 从而不会导致竞争引发的阻塞。

另外 调用park 的 线程可以响应中断 从而不会继续阻塞 而且提供的超时的park版本。
另外 park 可能会无缘无故的返回 ,所以通常建议使用循环检查条件 来判断其是否还是否需要再次park.
另外 一定要将parkunpark 成对使用

park 解释

三种形式的park 支持一个blocker 参数,该参数可以记录线程因为什么而阻塞,从而可以便于诊断和分析。getBlocker(Thread)可以获取到其blockers 对象。这些函数被设计用来为更高级的同步工具提供支撑。
park(Object blocker) 会调用UNSAFE.park() 进行阻塞,同时会设置调用线程的blocker .调用后 线程会处于休眠状态,并且不参与线程调度。
LockSupport.parkNanos(Object blocker,long nanos) 同样会使得线程处于休眠状态(如果线程没有permit 的话)。同样 若其他线程使得该线程中断 或者其他线程unpark 该线程 都会使得该线程继续运行。
其中 UNSAFE.park(boolean b,long v)第一个参数代表是否是绝对时间,第二个参数是时间。如果为true代表绝对时间,如果为false 代表为相对现在的时间。
所以我们在源代码中经常看到的UNSAFE.park(false,0L) 其实就是让线程立刻阻塞不参与线程调度。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值