锁优化

锁优化

有些时候, 必须加锁, 但能不能提升加锁的效率

锁优化(源自jdk6)

自旋锁

自适应锁

锁消除

锁粗化

偏向锁

互斥同步存在的问题,

挂起线程 和 恢复线程 都需要转入内核态中完成, 这些操作 给系统的并发性能, 带来很大的压力

1. 自旋锁

如果物理机有一个以上的 处理器 能让 两个 或 两个以上的 线程同时并行执行,

那就可以让后面请求的锁的那个线程 "稍等一会", 但不放弃处理器的执行时间

看看 持有锁的 线程 是否很快就会释放锁.

为了让 线程等待, 我们只需要让 线程执行一个 忙循环(自旋), 这项技术就是 自旋锁.

Java中 自旋次数, 默认10次

2. 自适应自旋

自适应, 意味着 锁自旋的 时间 不再固定, 而是由 前一次在 同一个锁上的 自旋时间 及 锁所有者的状态 来决定,

如果在 同一个锁对象上, 自旋等待 刚刚成功获得锁, 并且持有锁的线程 正在运行中, 那么虚拟机就会认为这次自旋也很有可能再次成功,

进而它允许等待 相当 更长的 一段时间

3. 锁消除

JVM即时编译器在 运行时, 对一些代码上要求同步, 但是 被检测到 不可能存在 共享数据竞争的锁进行消除

判定依据

如果判断在一段代码中, 堆上的所有数据都不会逃逸出去, 从而被其他线程访问到, 那就可以把 它们当做栈上数据对待,

认为它们是线程私有的, 同步加锁自然无需进行

4. 锁粗化

通常我们的代码总是 将 同步块的 作用范围限制得尽量小,

只在共享数据的 实际作用域中 才进行同步, 这样是为了 使得 同步操作的数量尽可能变小

另一种情况是, 如果一系列的连续操作都对 同一对象反复加锁,

甚至加锁操作 是 出现在 循环体中, 那即使没有 线程争用, 频繁的 进行 互斥同步也会导致 不必要的 性能损耗,

此时只需要将 同步块范围扩大即可, 即: 锁粗化

5. 偏向锁

目的: 消除数据 无竞争情况下的 同步原语, 进一步提高程序运行的性能.

偏向锁就是在 无竞争的情况下, 把整个同步都消除掉, 连CAS操作都不做

偏向: 意思是这个锁 会偏向 第一个获得它的线程, 如果在接下来的执行中, 该锁没有被其他线程获取, 则持有 偏向所得线程, 永远不需要再进行同步


小结

线程安全与线程兼容与对立

线程安全的实现方式

锁优化

参考链接

https://www.xuetangx.com/learn/THU08091000252/THU08091000252/7754101/video/12732941

posted on 2021-11-06 16:07  beyondx  阅读(58)  评论(0编辑  收藏  举报

导航