LockSupport原理

本文介绍了Java并发包中LockSupport的基本原理与应用。LockSupport利用park和unpark操作实现线程间的阻塞与唤醒,每个线程关联一个许可,通过许可的切换控制线程状态。此外还介绍了线程监控的相关方法。

1、使用
LockSupport和CAS操作是java并发包中很多控制机制的基础,都是通过UNSAFE来实现的。
LockSupport是基本的线程阻塞的原语,通过park和unpark来实现线程的阻塞和唤醒。LockSupport的每个使用它的线程都与一个许可(permit)有关,permit是一个0,1的开关,默认是0,unpark会将permit变为1。park会消耗permit,变为0,同是park马上返回。如果再调用一次park,则会阻塞再这里,直到unpark将permit变为1。
permit最多只有1个,重复调用unpark不会累计。

void park()
void unpark(Thread thread)

2、其他
LockSupport中有如下方法需要特别说明

//记录线程被谁阻塞的parkBlocker的偏移
private static final long parkBlockerOffset;
//记录线程是被谁阻塞的,用于线程监控及分析工具来定位原因
static Object getBlocker(Thread t){}
LockSupport是一个线程阻塞工具类,为Java并发包里的锁和同步类提供了线程阻塞原语,没有它就没有AQS,更没有上层的各类锁实现(例如ReentrantLock)、同步器(例如CountdownLatch)、阻塞队列等。其所有方法都是静态方法,可让线程在任意位置阻塞,阻塞之后也有对应的唤醒方法[^1][^3]。 ### 使用方法 LockSupport类中最常用的方法是`park()`和`unpark(Thread thread)`,分别用于阻塞和唤醒线程,作用类似于`wait/notify`方法。使用要点如下: - 线程调用`park`阻塞自己(类似`sleep`),直到中断、超时或者其它线程调用`unpark`。 - 线程调用`park`之前,如果其它线程调用了`unpark`,则会立即返回。 - 线程唤醒以后,线程并不知道是什么原因被唤醒,需要去判断时间、线程状态(`Thread.interrupted()`)。 - 线程`start`之前,`unpark`没有用,线程`start`之后`park`仍然会阻塞。 - 线程调用`park`阻塞不会释放线程占用的资源(锁)[^4][^5]。 以下是一个简单的示例代码: ```java public class LockSupportExample { public static void main(String[] args) { Thread thread = new Thread(() -> { System.out.println("线程开始执行"); LockSupport.park(); System.out.println("线程被唤醒,继续执行"); }); thread.start(); try { // 主线程休眠1秒,确保子线程先执行到park Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } // 唤醒子线程 LockSupport.unpark(thread); } } ``` ### 原理 LockSupport提供了线程阻塞原语,它为Java并发包中的锁和同步类奠定了基础。其提供的`park`和`unpark`方法实现了线程的等待和唤醒功能。从底层来讲,它是更底层的线程阻塞和唤醒机制,为上层的锁和同步机制提供了支持[^1][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值