深入java并发包源码(一)简介
in Java with 0 comment

深入java并发包源码(一)简介

in Java with 0 comment

深入java并发包源码(一)简介
深入java并发包源码(二)AQS的介绍与使用
深入java并发包源码(三)AQS独占方法源码分析

阅读本文章前需要了解 CAS 操作是什么。

首先大致介绍一下需要讲到的几个类,只需要理解这几个类是什么关系即可,后面会有详细解析。

Unsafe:这个类提供了 native 方法,未开源,提供了线程阻塞和唤醒,原子操作等方法。

LockSupport:包装了一层 Unsafe 类,非常类似于代理者模式,将在 Unsafe 类中的线程挂起唤醒等操作导出,避免将 UNSAFE 类引入代码造成复杂性上升,并且降低了耦合。

首先我们看一下以 ReentrantLock 为代表的并发工具与 JUC 底层类的关系。

AQS 类:用 Unsafe 类的 CAS 操作和 LockSupport 来实现锁的等待,具体实现在后面会分析。

ReentrantLock:实现了 Lock 接口,持有自定义的 AQS 内部类,通过 AQS 内部类实现锁的操作,然后将 AQS 映射到 Lock 接口上。

接下来仔细介绍一下这些类的实现

Unsafe

Unsafe 类有相当多的功能,比如内存管理,线程同步,对类和数组进行一些骚操作 。想要获取这个类需要用到利用 Java 反射。本篇文章只介绍一些关于并发的操作。

如果有兴趣可以去看一下这篇博客

说一说Java的Unsafe类

方法名功能
park()阻塞线程,可以通过参数控制挂起时间和是否可以被中断
unpark()唤醒线程
compareAndSwapObjectCAS 操作 Object
compareAndSwapIntCAS 操作 int

LockSupport

LockSupport 只是对 Unsafe 类进行封装了而已,下面的方法都是直接调用 UNSAFE 类中的方法。

方法名功能
park()阻塞线程
parkNanos(long nanos)阻塞线程,在 nanos 毫秒后唤醒
parkUntil(long deadline)阻塞线程,直到 deadline 时间
unpark(Thread thread)唤醒处于阻塞状态的线程

使用 synchronized 在 dump 线程的时候会带有当前线程正在等待对象的信息,然而使用这些方法得不到这些信息,开发人员疏漏了这点。所以在 LockSupport 在 Java 6 中添加了这几个方法。

方法名功能
park()阻塞线程,
parkNanos(Object blocker, long nanos)阻塞线程,在 nanos 毫秒后唤醒
parkUntil(Object blocker,long deadline)阻塞线程,直到 deadline 时间
unpark(Object blocker,Thread thread)唤醒处于阻塞状态的线程

blocker 就是当前线程正在等待的对象,使用下面表格的方法就可以把在 dump 线程的时候把等待的对象导出了。