一.锁:
1.属性划分:共享锁(可读,不可写),排它锁(不可读写)
2.机制划分:
乐观锁:1.给表加版本号,并且通过一种自悬的方式辅助实现
解释:处理数据不加锁,处理数据后对比版本号,看版本号是否冲突
悲观锁:
1.写锁是悲观锁的一种
2.悲观锁sql语句加锁用for update
3.解释:多线程对同一个数据的并发操作,一定是会被其他线程同时修改的,所以加锁
4.举例lock,synchronize锁
3.锁的粒度:行锁,表锁,页锁
二.分布式锁
之前的锁(锁虚拟机)不能解决,因为分布所锁有多个节点(多个虚拟机)。之前只是一个节点
解决思路:把锁提出来,锁多个线程
1.分布式锁常见的锁:
可重入锁
阻塞锁
公平锁
2.分布式锁的使用方式:数据库,redis,zuulkeepr,
1.数据库如何实现分布式锁:
创建一个锁表,查询SQL语句的时候,根据表唯一的主键id,把这个id存入锁表
等该线程SQL语句操作完成后,操作锁表删除主键id
2.redis如何实现分布式锁:
理解:多个线程去改锁的状态,0或者1嘛
在redis存入一个数据,通过redis的setnx指令,作为锁的标识,锁存在返回1,不存在返回0
坏处:redis锁,在锁住数据后宕机了,那就死锁了。
解决死锁:给锁设置一个过期时间
锁的原子性:就是这个锁一定是当前线程操作的
lua脚本保证原子性
3.redisson实现分布式锁:(详情请看墨家巨子-俏如来)
导入redissonClient,
然后redissonClient.getxxx锁(信号量(避免超卖,要根据数据库数量来),红锁(10个虚拟机,瓦了3个,还是可以用),公平锁,闭锁(结果汇总))
redisson的看门狗原理:检查改事务中锁的一个过期时间,快过期了就续期
4.zookeeper实现分布式锁:
1.临时节点+重试:会导致线程饥饿
通过临时节点来站位置,然后加锁
临时顺讯节点+watch:可以在第一个节点消失后,让后面的线程来抢占节点时,有顺序