一、java中的锁如下图
二、相关锁的概念
1、乐观锁
概念:读不上锁、写进行上锁(保证原子性)
详解:
【读数据时】会很乐观的认为别的线程没有在修改数据,所以不会上锁。
【写数据时】会判断当前值和期望值一不一样,一样的话会进行修改,此时修改会加锁。
容易产生ABA问题,解决ABA问题可以使用版本号或者时间戳
2、悲观锁
概念:读写都进行上锁。
【读/写数据时】悲观的认为别人会更改数据。
synchronized、ReentrantLock 这两种锁都可以实现
3、公平锁
概念:多个线程按照申请锁的顺序来获取锁。
原理:主要依赖于维护这个锁的 「等待队列」,当队列为空时就直接占有锁, 不为空就加入到 「等待队列」 的末尾,然后按照 「FIFO」 的原则去获取锁。
new ReentrantLock(true) 可以实现
4、非公平锁
概念:多个线程 不按照先到先得的方式去获取锁, 有可能后申请的线程会先得到锁
原理:非公平锁会尝试获取锁,失败的话会加入到 「等待队列」 的末尾,然后按照 「FIFO」 的原则去获取锁 ,变成公平锁的方式
5、独享锁(独占锁)
独自占有锁,不和其他线程共享~, 和 互斥锁,排他锁,悲观锁 同义
概念:只允许一条线程占有改锁。
实现方式:synchronized ,ReentrantLock 还有 ReentrantReadWriteLock 中 的 「写锁」
6、共享锁
可以和其他线程共享该锁 和 乐观锁,读写锁 同义
概念:锁可被多个线程所持有
实现方式:ReentrantReadWriteLock ,ReadWriteLock 这两个中的 读锁
7、互斥锁(同步锁)
可以理解为独占锁的具体实现
概念:表示该资源只能被一条线程访问,不能被其他访问
实现方式:synchronized ,ReentrantLock
8、读写锁
顾名思义~ 有读锁和写锁
- 读读不互斥
- 读写互斥
- 写写互斥
概念:表示该资源允许 「多条持有读锁的线程共同访问,但是只允许一条持有写锁的线程独占」
9、可重入锁(递归锁)
概念:当一个线程持有某个锁时,「可以再次获取该锁而不会导致死锁或者阻塞」
实现方式:synchronized ,ReentrantLock
10、分段锁
概念:CurrentHashMap 中 的 Segment 数组 ,put 操作时会调用 ReentrantLock 的 lock 方法,锁住该 Segment
11、自旋锁
让线程不断地循环,去尝试获取锁
12、死锁
线程1 拥有 资源A 的锁,线程2 拥有 资源B 的锁,但是线程1在持有A锁的情况下,还想拥有B锁。同理 线程2在持有B锁的情况下,还想拥有A锁。他们两就这样僵持着,互相等待对方释放锁🔒
概念:死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。
13、锁升级(无锁->偏向锁->轻量级锁->重量级锁)