java 并发编程工具类之LockSupport
概述
在java中和并发相关的自然是锁了,前面的小节中我们看到的java给我们提供的语言级别的同步原语,下面我们会继续看一下java中的并发编程框架: AQS以及由此衍生而来的各种锁和工具类,不过在进入正题之前,我们还是先看一下支撑AQS框架的类,这样分析起来才有根据。
LockSupport
在java中current包基于AQS框架,而AQS框架基于两个类:
- LockSupport:提供park、unpark操作(是Unsafe的一个代理,最终调用的还是Unsafe的park、unpark操作)
- Unsafe :提供CAS操作(一般是通过自旋的方式进行操作,这里的cas应该是使用TSL指令来完成的)
在前面线程状态分析的总结中我们看到了locksupport的park操作最终会是的当前线程进去waiting状态,我们知道Object的wait方法也会 使得当前线程进入waiting的状态,那么两者有什么区别呢?
- 区别1:locksupport不需要当前线程获取到锁,其所做的操作就仅仅是暂停当前线程,而Object是需要在同步代码块中执行
- 区别2:locksupport操作的对象是线程,而Object的wait方法操作的对象是object(locksupport操作的过程有点像是线程内部包含了一个object,该object不共享,其作用和java的Object是类似的,下面将给出分析)
- 区别3:locksupport是精准打击(狙击),而Object是针对一片线程进行的打击(散弹),这样Object的notify最终唤醒的线程就不确定了
java 线程源码
从线程源码的视角来看一下locksupport的park、unpark操作分别做了什么或许就比较好理解上文lockspport的park以及object的wait的区别了。
1 | private: |
如上,在每一个java线程内部都包含了一个Parker对象,该对象内部维护了一个_counter变量,变量初始值为0,当我们调用park方法的时候,会将 该变量置位为1,而当我们调用unpark的时候则将该变量进行复位,我们看到该变量起到的作用就是一个信号量的作用, 不过该信号量无法积累,最大只能为1。 类比Object的wait方法,该变量就好像是在java线程的内部保存了一个object变量,调用park操作的时候,就有点类似于调用该内部类object的wait方法, 只不过park操作的对象是线程私有的。
总结
这里简单的分析了一下AQS所依赖的基本的类的操作,并通过线程源码的方式描述了locksupport的park、unpark在线程层面上的影响,后面如果有时间的 话,再学习一下c++的基本语法,不然在往下分析就分析不动了