java锁体系

1.java中锁体系

  1. 乐观锁,悲观锁
  2. 读锁(共享锁),写锁(排他锁)
  3. 自旋锁,非自旋锁
  4. 无锁,偏向锁,轻量级锁,重量级锁
  5. 分布式锁
  6. 区间锁(分段锁)java.util.concurrent ConcurrentHashMap
  7. 重入锁,非重入锁
  8. 公平锁,非公平锁

在这里插入图片描述

2.乐观锁,悲观锁

  • 悲观锁:悲观的认为自己在使用数据时一定有别的线程来修改数据,在获取数据时会先加锁,确保数据不会被别的线程修改
    锁实现:关键字synchronized、接口Lock的实现类
    适用场景:写操作较多,先加所可以保证写操作时数据正确
  • 乐观锁:乐观的认为自己在使用数据时不会有别的线程修改数据,所以会加锁,只是在更新数据的时候去判断之前有没有别的线程更新了这个数据
    锁实现:CAS算法,例如AtomicInteger类的原子自增是通过CAS自旋实现
    适用场景:读操作较多,不加锁的特点能够使其读操作的性能大幅提升
  • CAS算法
    Compare And Swap(比较与交换)
    无锁算法:基于硬件源语,在不使用锁(没有线程阻塞)的情况下实现多线程之间的变量同步
    JDK中实现:java.util.concurrent包中原子类就是通过CAS来实现了乐观锁
    算法涉及到三个操作数:
    需要读写的内存值 V
    进行比较的值 A
    要写入的新值 B
    在这里插入图片描述
  • CAS存在的问题?
  1. ABA问题?解决:AtomicStampedReference在变量前面添加版本号,每次变量更新时把版本号加1
    在这里插入图片描述
  2. 循环时间长开销大
  3. 只能保证一个共享变量的原子操作?解决:AtomicReference类来保证引用对象之间的原子性,可以把多个变量放在一个对象里来进行CAS操作

3.自旋锁

  • 概念:当一个线程在获取锁的时候,如果锁已经被其他线程获取,那么该线程将循环等待,然后不断的判断锁是否能够被成功获取,自旋直到获取到锁才会退出循环
  • 自旋锁存在的意义和使用场景
    1.阻塞与唤醒线程需要操作系统切换cpu状态,需要消耗一定时间
    2.同步代码块逻辑简单,执行时间短
  • 分类
  1. 自旋锁
  2. 自适应自旋锁
    自适应自旋锁假定不同线程持有同一个锁对象的时间基本相当,竞争度趋于稳定,因此可以根据上一次自旋的时间与结果调整下一次自旋的时间
    jdk6通过-XX:-UseSpinning参数关闭自旋锁优化;-XX:PreBlockSpin参数修改默认的自旋次数
    jdk>=7自旋锁参数被取消,虚拟机不再支持用户配置自旋锁,自旋锁总是会执行,自旋锁次数由虚拟机自动调整。

在这里插入图片描述

3.1进程与线程上下文切换为什么耗资源原理解析

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
多个cpu共用一个寄存器
在这里插入图片描述

4. synchronized ,悲观锁

  • synchronized使用方式
  1. 同步实例方法,锁是当前实例对象
  2. 同步类方法,锁是当前类对象
  3. 同步代码块,锁是括号里的对象
  • synchronized实现方式
    synchronized是JVM内置锁,通过内部对象Monitor(监视器锁)实现,基于进入与退出Monitor对象实现方法与代码块同步,监视器锁的实现依赖底层操作系统Mutex lock(互斥锁)实现
    在这里插入图片描述
  • Monitor
    在这里插入图片描述
  • JVM内置锁的膨胀升级
    JDK>1.6中synchronized的实现进行了优化,如适应性自旋 、锁消除、锁粗化、偏向锁、轻量级锁
    在这里插入图片描述
  • JVM对象加锁原理
    对象的内存结构:
    1.对象头:比如hash码,对象所属的年代,对象锁,锁状态标志,偏向锁(线程)ID,偏向时间,数组长度(数组对象)等
    2.对象实际数据:即创建对象时,对象中成员变量,方法等

ps: Q:实例对象时怎么存储的?
A:对象地实例存储在堆空间,对象地元数据存在元空间,对象的引用存在栈空间。

在这里插入图片描述

  • 锁状态
    Mark Word在32位JVM中存储内容为例
    在这里插入图片描述

5. AQS原理(AbstractQueuedSynchronizer源码)

ReentrantLock为例
ps:
隐式锁(synchronized,基于JVM的内置锁),加锁与解锁的过程不需要我们在代码中人为地控制,jvm会自动去加锁和解锁
显式锁:ReentrantLock,可重入锁,整个加锁跟解锁过程需要手动编写代码去控制

  • AbstractQueuedSynchronizer:抽象队列同步器,基于CLH队列实现

在这里插入图片描述

在这里插入图片描述

6. AQS中的CLH队列,条件队列(公平锁)

  • CLH队列是Craig、Landin、Hagersten三人发明的一种基于双向链表数据结构的队列,java中的CLH队列是元CLH队列的一个变种,线程由原来的的自旋机制改为阻塞机制,所以ReentrantLock是悲观锁
    在这里插入图片描述
    CLH入队时用自旋
    在这里插入图片描述

7. 非公平锁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值