源码分析--LockSuppoprt

16 篇文章 0 订阅

概述

1、LockSupport是Java6引入的一个工具类, 用于挂起和唤醒线程;
2、所有的方法都是静态方法,可以让线程在任意位置阻塞,当然阻塞之后肯定得有唤醒的方法。
3、通过提供park() 和 unpark() 方法实现阻塞线程和解除线程阻塞, 实现阻塞与解除阻塞是基于许可(permit), permit相当于一个信号量,只能取0和1, 默认为0;

源码分析

构造方法:
只有一个无参构造方法,无需解析。
重要属性:

    private static final sun.misc.Unsafe UNSAFE;
    private static final long parkBlockerOffset;
    private static final long SEED;
    private static final long PROBE;
    private static final long SECONDARY;

主要是UNSAFE和parkBlockerOffset:

UNSAFE: Unsafe对象, 提供CAS操作, 获取对象内存中字段的偏移量, 设置对象偏移量对应的字段的值;
parkBlockerOffset 存储Thread类对象中parkBlocker字段的偏移量;

常用方法:

// UNSAFE.park第一个参数var1表示是否为相对时间, 第二个参数var2为超时等待时间
// var1为fasle时, var2的单位为纳秒, var2为0时, 会一直等待, 直到被unpark()唤醒或者被中断后才会向下执行;
// var2为true时, 表示绝对时间, var2单位为毫秒 
public static void park() {
    UNSAFE.park(false, 0L); 
}
// 唤醒thread线程, 对一个thread调用一次和多次效果一样;
public static void unpark(Thread thread) {
    if (thread != null)
        UNSAFE.unpark(thread);
}

可以看出,LockSupport 是基于 sun.misc.Unsafe 实现的。

LockSupport的设计思路就是为每一个线程设置一个许可(permit),其实就是一个值。这个permit就相当于一个开关,0代表关闭,1代表打开。默认是0的状态。调用一次unpark就加1变成1,调用一次park会消费permit, 也就是将1变成0,同时park立即返回。再次调用park会变成block(因为permit为0了,会阻塞在这里,直到permit变为1), 这时调用unpark会把permit置为1。每个线程都有一个相关的permit, permit最多只有一个,重复调用unpark也不会积累,也就是说你可以重复调用多次unpark方法这个值也一直是1,而不会因为多次调用而累加,调用一次park后这个值就会变成0,线程就会被阻塞。你也可以先调用unpark方法,将值先设置为1,然后再调用park方法,调用park方法时这个permit已经时1了那么就会立即返回,不会阻塞线程,并且将permit设置为0.这就是开篇说到的与Thread.suspend()和resume()由于先后顺序而产生的死锁的区别。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值