栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

javaEE学习总结(三)多线程--锁策略

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

javaEE学习总结(三)多线程--锁策略

一、乐观锁与悲观锁

悲观锁:在每次拿数据的时候都会上锁。
乐观锁:在数据提交更新的时候,才会正式对数据是否冲突进行检测,如果发现并发冲突了,则让返回用户错误的信息,让用户决定如何去做。

synchronized初始使用乐观锁策略。当发现锁竞争比较频繁的时候,就会自动切换成悲观锁策略。

二、读写锁

读写锁就是把读操作和写操作区分对待。
读读不互斥;
读写/写写互斥;

Synchronized不是读写锁

三、重量级锁和轻量级锁

重量级锁:加锁机制重度依赖OS提供的mutex互斥锁。
轻量级锁:加锁机制尽可能不适用mutex,而是尽量在用户态代码完成。

四、自旋锁

如果获取锁失败,立即再次尝试获取锁,无线循环,直到获取到锁为止。第一次取锁失败,第二次的尝试会在极短的时间内到来。
优点:没有放弃CPU,不涉及线程阻塞和调度,一旦锁被释放,就能第一时间获取到锁。
缺点:如果锁被其他线程持有的时间比较久,那么就会持续消耗CPU的资源。

五、公平锁和非公平锁

公平锁: 遵守 “先来后到”. B 比 C 先来的. 当 A 释放锁的之后, B 就能先于 C 获取到锁.
非公平锁: 不遵守 “先来后到”. B 和 C 都有可能获取到锁.

synchronized 是非公平锁.

六、可重入锁 和不可重入锁

可重入锁的字面意思是“可以重新进入的锁”,即允许同一个线程多次获取同一把锁。不可重入锁在递归过程中这个锁会阻塞自己。

Java里只要以Reentrant开头命名的锁都是可重入锁,而且JDK提供的所有现成的Lock实现类,包括
synchronized关键字锁都是可重入的
Linux 系统提供的 mutex 是不可重入锁

七、CAS
  1. CAS: 全称Compare and swap

乐观锁基于CAS机制实现。

一个 CAS 涉及到以下操作:
我们假设内存中的原数据V,旧的预期值A,需要修改的新值B。
(1) 比较 A 与 V 是否相等。(比较)
(2) 如果比较相等,将 B 写入 V。(交换)
(3)返回操作是否成功

  1. CAS 的 ABA 问题
  • ABA 的问题:
    假设存在两个线程 t1 和 t2. 有一个共享变量 num, 初始值为 A;
    接下来, 线程 t1 想使用 CAS 把 num 值改成 Z, 那么就需要
    先读取 num 的值, 记录到 oldNum 变量中;
    使用 CAS 判定当前 num 的值是否为 A, 如果为 A, 就修改成 Z;
    但是, 在 t1 执行这两个操作之间, t2 线程可能把 num 的值从 A 改成了 B, 又从 B 改成了 A;
  • 解决方案
    给要修改的值, 引入版本号. 在 CAS 比较数据当前值和旧值的同时, 也要比较版本号是否符合预期.
    CAS 操作在读取旧值的同时, 也要读取版本号.
    真正修改的时候,
    如果当前版本号和读到的版本号相同, 则修改数据, 并把版本号 + 1.
    如果当前版本号高于读到的版本号. 就操作失败(认为数据已经被修改过了)
八、Synchronized的锁优化原理
  1. Synchronized 基本特点
    结合上面的锁策略, 我们就可以总结出, Synchronized 具有以下特性(只考虑 JDK 1.8):
    (1) 开始时是乐观锁, 如果锁冲突频繁, 就转换为悲观锁.
    (2) 开始是轻量级锁实现, 如果锁被持有的时间较长, 就转换成重量级锁.
    (3) 实现轻量级锁的时候大概率用到的自旋锁策略
    (4) 是一种不公平锁
    (5) 是一种可重入锁
    (6) 不是读写锁
  2. 加锁过程
    JVM 将 synchronized 锁分为 无锁、偏向锁、轻量级锁、重量级锁 状态。会根据情况,进行依次升级。
    (1) 偏向锁
    第一个尝试加锁的线程, 优先进入偏向锁状态.偏向锁不是真的 “加锁”, 只是给对象头中做一个 “偏向锁的标记”, 记录这个锁属于哪个线程.
    (2) 轻量级锁
    随着其他线程进入竞争, 偏向锁状态被消除, 进入轻量级锁状态(自适应的自旋锁).
    此处的轻量级锁就是通过 CAS 来实现。
    (3) 重量级锁
    如果竞争进一步激烈, 自旋不能快速获取到锁状态, 就会膨胀为重量级锁
    此处的重量级锁就是指用到内核提供的 mutex
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/891213.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号