简述synchronized、lock和原子类的原理

本文探讨了Java中的synchronized与Lock(如ReentrantLock和ReentrantReadWriteLock)的区别,涉及锁的公平性、可重入性、底层实现(AQS与CAS),以及它们在性能和并发控制上的特点。

一、Synchronized

synchronized是一个基于jvm的重量级的锁,他可以保证线程的绝对安全,但是也有一些问题:比如它是非公平的,它的性能不高。
它的底层原理实际上是在jvm有一个是类似于计数器的东西叫做monitor,它默认情况下是0,但我们加锁的时候就+1变为1,解锁就是-1变为0,由于Synchronized是一个对象锁,所以它只能允许带有对象头的对象来进行加锁解锁操作,当对象进行加锁时会执行指令monitor enter,当解锁时执行monitor exit。
除此之外它还有一些特性:比如可重入锁、非公平锁。
可重入锁就是说如果我是同一个对象,那我在加锁一次后再去执行加锁,monitor会继续+1,比如从1变为2,以此类推,当解锁时同样时解锁一次就-1,直至为0.
非公平锁就是说,如果这个monitor不为0,就是上锁之后,别的对象想加锁,就只能全部等待,直到monitor为0之后,就会一起上去抢夺这把锁,这有点类似于zookeeper的羊群效应,它不会根据你先来后到的顺序,而是谁抢到就是谁的。

二、Lock

Lock锁有几种,简单介绍两种, ReentrantLock和ReentrantReadWriteLock,字面意思可以看出来一个是可重入锁,一个是可重入读写锁,可重入就是说我同一个线程加锁之后,我可以再拿到这把锁,而不会死锁,读写锁的意思就是它可以针对读和写操作去进行加锁和解锁。
谈lock锁之前先要聊聊AQS,因为上面两种lock锁的底层都是AQS实现的,那么 AQS 的全称是什么呢?AbstractQueuedSynchronizer,抽象队列同步器。AQS本质上是lock内部的一个对象,他有一个关键变量state,它其实也类似于一个计数器,说起计数器在联想上面的monitor,其实AQS的加锁解锁原理也呼之欲出了。
在这里插入图片描述
但是我们可以看到state有一个问题,因为他不是基于jvm的,所以如果我多个线程去加锁,都去更新这个state,那么显然会有问题,那是怎么解决的呢?这里就引出了原子类,state是一个原子类型,原子类的底层是CAS,全称是比较后再设置,顾名思意就是我要去设置这个值,先要去询问一下有没有别的线程改了这个值,如果没人改我才去设置。
另外AQS还有一个等待队列,就是说如果已经加锁了,多个线程去等待,会被放入一个等待队列按照先来后到的顺序去加锁,所以lock锁是一把公平锁。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值