1.什么是悲观锁?什么是乐观锁?
悲观锁:
站在mysql的角度分析,悲观锁就是比较悲观,当多个线程对同一行数据时间修改的时候,最后只有一个线程才能修改成功,只要谁能够对获取到航锁则其他线程时不能够对该数据做任何修改操作,且是阻塞状态。
站在java锁层面,如果没有获取到锁,则会阻塞等待,后期唤醒的锁的成本就会很高。从新从就绪转为运行状态。
乐观锁:
获取锁---如果没有获取到锁,当前线程是不会阻塞等待,通过死循环控制。
注意: mysql的innodb引擎中存在行锁的概念
Mysql层面如何实现乐观锁
在我们表结构中,会新增一个字段就是版本字段 version varchar(255) default null
多个线程对同一行数据实现修改操作,提前查询当前最新的version版本号码,作为uodate条件查询,如果version版本发生变化,则查询不到该数据,表示修改失败,不断充实。从新查询中最新版本实现update.
java层面实现乐观锁
1.CAS(无锁)(juc并发包框架原子类)(结合自旋)
底层基于修改内存只(V) ,E (旧的预期值)
E==V 则表示修改v=n
2.基于 cas实现无锁机制
原理:变量===0
0 表示没有线程获取该锁;
1表示已经有线程获取到该锁;
cas获取锁:
cas 修改该变量=0,1=cas 修改成功的话则表示获取锁成功
cas释放锁 变量1,0 cas释放锁成功。
2.Java有哪些锁的分类
- 悲观与乐观锁
- 公平锁与非公平锁
- 自旋锁/重入锁
- 重量级锁与轻量级锁
- 独占锁与共享锁
3.公平锁与非公平锁之间区别
公平锁:比较公平,先请求的先获取锁。链表的形式做存放。队列实现
非公平锁:不是根据请求顺序获取,通过争抢的方式获取锁,
非公平锁效率比公平锁的效率要高,Synchronized是公平锁。
new ReentrantLock(true) ----> 公平锁
new ReentrantLock(false) ----> 非公平锁
4.什么事锁的可重入性
在同一个线程中锁可以不断传递,可以直接获取
5.什么是CAS(自旋锁),它的优缺点
CAS: compare and swap 翻译 比较交换
没有获取到锁的线程是不会组赛的,通过循环控制一直不断的获取锁。执行函数CAS(V,E,N)
CAS有三个操作数,内存值V, 旧的预期值E, 要修改的新值N.当且仅当预期值E和内存值V相同时,将内存值V修改为N,否则什么都不做。
CAS无锁机制原理:
1.定义一个锁的状态;
2.状态值=0,则表示没有线程获取到该锁;
3.状态值=1,则表示有线程已经持有该锁;
实现细节:
CAS获取锁:
将该锁的状态从0改为1-----能够修改成功cas成功则表示获取锁成功
如果获取锁失败---修改失败,则不会阻塞而是通过循环(自旋来控制重试)CAS释放锁
该锁的状态从1改为0 如果能够修改成功 cas成功则表示释放锁成功。
优点:没有获取到锁的线程,会一直在用户状态,不会阻塞,没有锁的线程会一直通过循环控制重试。
缺点:通过死循环控制,消耗cpu资源比较高,需要控制循环次数,避免cpu飙高问题。
6.CAS如何解决ABA问题
加版本号 区别V的值变化过程