加入收藏 | 设为首页 | 会员中心 | 我要投稿 惠州站长网 (https://www.0752zz.com.cn/)- 办公协同、云通信、物联设备、操作系统、高性能计算!
当前位置: 首页 > 业界 > 正文

发布2020年度程序员收入报告

发布时间:2021-02-01 10:11:56 所属栏目:业界 来源:互联网
导读:11.2 AQS底层 上题我们用到了ReentrantLock、Condition ,但是它们的底层是如何实现的呢?其实他们是基于AQS的 同步队列 跟 等待队列 实现的! 11.2.1 AQS 同步队列 学AQS 前 CAS + 自旋 + LockSupport + 模板模式 必须会,目的是方便理解源码,感觉比 Synchro

11.2 AQS底层

上题我们用到了ReentrantLock、Condition ,但是它们的底层是如何实现的呢?其实他们是基于AQS的 同步队列 跟 等待队列 实现的!

11.2.1 AQS 同步队列

学AQS 前 CAS + 自旋 + LockSupport + 模板模式 必须会,目的是方便理解源码,感觉比 Synchronized 简单,因为是单纯的 Java 代码。个人理解AQS具有如下几个特点:

  1. 在AQS 同步队列中 -1 表示线程在睡眠状态
  2. 当前Node节点线程会把前一个Node.ws = -1。当前节点把前面节点ws设置为-1,你可以理解为:你自己能知道自己睡着了吗?只能是别人看到了发现你睡眠了!
  3. 持有锁的线程永远不在队列中。
  4. 在AQS队列中第二个才是最先排队的线程。
  5. 如果是交替型任务或者单线程任务,即使用了Lock也不会涉及到AQS 队列。
  6. 不到万不得已不要轻易park线程,很耗时的!所以排队的头线程会自旋的尝试几个获取锁。
  7. 并不是说 CAS 一定比SYN好,如果高并发执行时间久 ,用SYN好, 因为SYN底层用了wait() 阻塞后是不消耗CPU资源的。如果锁竞争不激烈说明自旋不严重 此时用CAS。
  8. 在AQS中也要尽可能避免调用CLH队列,因为CLH可能会调用到park,相对来耗时。

ReentrantLock底层:

很显然,这不是线程安全代码,产生bug的原因也很简单,你在使用该变量前其值可能已经被其它线程修改了。因为该函数使用了一个静态全局变量,只要能拿到该变量的地址那么所有线程都可以修改该变量的值,因为这是线程间的共享资源,不到万不得已不要写出上述代码,除非老板拿刀架在你脖子上。但是,请注意,有一个特例,这种使用方法可以用来实现设计模式中的单例模式,就像这样:
 

各个线程对global_num的修改不会影响到其它线程,因为是线程私有资源,因此func函数是线程安全的。说完了局部变量、全局变量、函数参数,那么接下来就到函数返回值了。

函数返回值

这里也有两种情况,一种是函数返回的是值;另一种返回对变量的引用。

1,返回的是值

我们来看这样一段代码:
 

当一个线程执行test1()方法的时候,需要获取rentrantLockDemo的对象锁,在test1方法汇总又会调用test方法,但是test()的调用是需要获取对象锁的。

可重入锁也叫「递归锁」,指的是同一线程外层函数获得锁之后,内层递归函数仍然有获取该锁的代码,但不受影响。

ThreadLocal设计原理

ThreadLocal名字中有个Thread表示线程,Local表示本地,我们就理解为线程本地变量了。

先看看ThreadLocal的整体:

(编辑:惠州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章
    热点阅读