锁,Synchronized,volatile

锁,Synchronized,volatile

前言
配合上篇Java内存模型(JMM)一起看效果更好。本来想写在一篇了。但是太长了。想想还是分开
理解了 Java内存模型,这个其实比较简单

锁 volatile synchronized

1. volatile

JMM内存模型
还是这张图:volatile变量的写相当于立即把更改的数据更新到主内存,读相当于将本地内存总的地址置为无效,每次从主内存中读取

内存语义的实现:屏蔽重排序(具体的做法咱也不记得了)

volatile变量具有原子性(简单操作是原子性,复杂操作就不是原子性)
happens-before的体现,前一个线程结果对后一个线程可见

2. 锁

2.1 锁是什么

控制多个操作访问共享资源的一种方式。目的就是避免多个线程同时操作一个资源,导致结果不可控。
内存语义:释放锁时将变量的更改刷新到内存(volatile写类似);获取锁时将本地内存地址置为无效(volatile读类型)

2.2 Synchronized 虚拟机实现的锁

synchronized是有虚拟机实现的锁。每个对象都有一个monitor锁
通过monitorenter和monitorexit 加锁和释放锁
可以①对方法加锁(锁实例对象)②对静态方法加锁(锁类对象,class对象)③对代码块加锁(锁代码里的对象)
synchronized优化后(1.6优化的?)引入了偏向锁,轻量锁。之前都是重量级锁(加锁和释放锁比较吃资源,需要阻塞线程)
偏向锁:在对象头里存储了线程的ID,获取锁前判断是否是该线程,是则获取到锁。适用于没有竞争的情况
轻量锁:如果上面的线程获取锁的时候发现对象头里面的额线程ID不是自己(你心里居然有了别人)。就升级为轻量锁。等待几次CAS自旋后获取锁。适用于竞争小的情况下
重量级锁:上面的轻量量级锁发现CAS自旋了几次还是无法获取到锁,这个时候就升级为重量级锁。就是普通的synchronized锁了。会阻塞线程
上面的过程就是锁升级。锁无法降级

2.3 Java代码实现的锁

CAS compare and swap 比较并交换。如值时预期的数据,更换成我给的数据。Java通过这种方式来实现原子操作。Redis也是这种方式。其实比较常见

volatile 上面介绍的。
Java代码实现的锁核心就是这两种方式

强调:不是说Java代码实现的锁效率更高,只是更灵活罢了
AQS AbstractQueuedSynchronizer 抽象队列同步器,一般就叫同步器。一般面试就这个问得比较多 包含:锁状态,存放线程的队列
ReentrantLock是面向锁的使用者。AQS这是面向锁的实现者。例如ReentrantLock就是利用AQS实现。内部类继承AQS 。AQS屏蔽了锁实现的细节。具体的不记得了,在IDEA里面通过ctrl B 可以看到直接追溯到源码看

Java代码实现的锁:
ReentrantLock(可重入锁)
ReentrantReadWriteLock(读写锁,读锁共享,写锁独占):看名字也知道,读的优先级比写高一点(在同一个线程下。如果在写操作,其读操作可以预读,就是写锁还没释放,读锁先获取到了,再释放写锁。预写是不行的。预读是有条件的:在同一个线程下)

3. 小结

  • volatile就是JMM里面可见性,或者说happens-before的体现。其实就是将马上更新主内存,而且这个值每次获取都是从主内存获取
  • volatile 实际上用的很少的(当然在线程池里面很常见。但是都是人家封装好的,我们不用太费心)
  • synchronized是sun公司亲儿子,经过优化后有偏向锁,轻量锁,重量级锁,并不全是重量轻锁,一般用这个就足够了。
  • Java实现的锁:ReentrantLock,ReentrantWriteReadLock这个和synchronized的区别在于哪了。:“高玩用自定义模式,普通玩家用默认模式”。Java实现的锁就是哪个自定义模式。有synchronize的功能,同时也有自己特有的功能:超时获取,非阻塞式获取,能够被中断获取。有条件的获取和释放锁
  • Java实现的锁—AQS—volatile和CAS

先这样吧
总目录:Java进阶之路-目录

                空山新雨后,天气晚来秋,明月松间照,清泉石上流
                《山居秋暝》 王维
                博主:五更依旧朝花落
                首次发布时间:2020年5月8日21:22:54
                末次更新时间:2020年5月19日11:57:51 修改一些错误
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值