LockSupport源码详细分析

一. LockSupport类介绍

前面分析中,阻塞和唤醒线程都会使用到LockSupport工具来完成相应工作,LockSupport定义了一组公共静态方法,这些方法提供了最基本的线程阻塞和唤醒公共,而LockSupport也成为构建同步组件的基础工具。

 

LockSupport定义了一组以park开头的方法用来阻塞当前线程,以及upark方法用来唤醒线程。这些方法如下所示:

方法名称 描述
void park() 阻塞当前线程,如果调用unpark(Thread)或者当前线程被中断,才能从park()方法返回
void parkNanos(long nanos) 阻塞当前线程,最长不超过nanos纳秒,返回条件在park()的基础上增加了超时返回
void parkUntil(long deadline) 阻塞当前线程,直到deadline
void unpark(Thread thread) 唤醒处于阻塞的线程thread

三种形式的 park 还各自支持一个 blocker 对象参数。此对象在线程受阻塞时被记录,以允许监视工具和诊断工具确定线程受阻塞的原因。(这样的工具可以使用方法 getBlocker(java.lang.Thread) 访问 blocker。)建议最好使用这些形式,而不是不带此参数的原始形式。在锁实现中提供的作为 blocker 的普通参数是 this。
看下线程dump的结果来理解blocker的作用。

从线程dump结果可以看出:
有blocker的可以传递给开发人员更多的现场信息,通过jstack命令可以非常方便的监控具体的阻塞对象,方便定位问题。所以java6新增加带blocker入参的系列park方法,替代原有的park方法。

 

Unsafe的park和unpark

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

/**
 * 为指定线程提供“许可(permit)”
 */
public native void unpark(Thread jthread);

/**
 * 阻塞指定时间等待“许可”。
 * @param isAbsolute: 时间是绝对的,还是相对的
 * @param time:等待许可的时间
 */
public native void park(boolean isAbsolute, long time);  

上面的这个“许可”是不能叠加的,“许可”是一次性的。

比如线程B连续调用了三次unpark函数,当线程A调用park函数就使用掉这个“许可”,如果线程A再次调用park,则进入等待状态。

注意,unpark函数可以先于park调用。比如线程B调用unpark函数,给线程A发了一个“许可”,那么当线程A调用park时,它发现已经有“许可”了,那么它会马上再继续运行。

可能有些朋友还是不理解“许可”这个概念,我们深入HotSpot的源码来看看。

每个java线程都有一个Parker实例,Parker类是这样定义的:

class Parker : public os::PlatformParker {  
private:  
  volatile int _counter ;  
  ...  
public:  
  void park(bool isAbsolute, jlong time);  
  void unpark();  
  ...  
}  
class PlatformParker : public CHeapObj<mtInternal> {  
  protected:  
    pthread_mutex_t _mutex [1] ;  
    pthread_cond_t  _cond  [1] ;  
    ...  
}  

可以看到Parker类实际上用Posix的mutex,condition来实现的。在Parker类里的_counter字段,就是用来记录所谓的“许可”的。

当调用park时,先尝试直接能否直接拿到“许可”,即_counter>0时,如果成功,则把_counter设置为0,并返回:


                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值