Skip to content

Latest commit

 

History

History
66 lines (38 loc) · 2.86 KB

lock.md

File metadata and controls

66 lines (38 loc) · 2.86 KB

导航

ID Problem Article
000 公平锁 解决思路
001 非公平锁 解决思路
002 可重入锁 解决思路
003 递归锁 解决思路
004 自旋锁 解决思路
005 手写自旋锁 解决思路

公平锁 和 非公平锁

公平锁:类似食堂打饭,按照申请锁的顺序来获取锁类似厕所蹲坑先来后到

公平锁就是很公平 在并发环境下每个线程在获取锁的同时会先查看此锁维护的等待队列,如果为空,或者当前线程是等待就占有锁,否则就加入到等待队列中,以后会按照FIFO的规则从队列中取到自己

非公平锁: 多线程获取锁的顺序并不是按照申请锁的顺序,有可能后申请的线程比先申请的线程优先获取到锁,在高并发的情况下可能造成优先级反转和饥饿现象

非公平锁上来就尝试占有锁,如果占有失败,在采取类似公平锁的方式 com.geek.lockthinkdemo.fairLock 示例

并发包ReentrantLock的创建可以指定构造函数的boolean类型来得到公平锁或者非公平锁 默认是非公平锁

优势

非公平锁的优点在于吞吐量必公平锁大 对于synchronized而言 也是一种非公平锁.

可重入锁(递归锁)

只在同一个线程外层函数获取锁后,内层递归函数仍然能够获取该所得代码在同一个线程在外层获取所得时候,进入内层会自动获取锁也就是说 线程可以进入任何一个他已经拥有的锁所同步者的代码块

ReentrantLock 和synchronized 典型的可重入锁 可避免死锁

ReenterLockDemo 示例

自旋锁

尝试获取锁但是不会立刻阻塞,而是采用循环的方式来尝试获取锁 优点 减少上下文切换 缺点 循环会消耗CPU

类似于 我要向老师问题 但是老师有事在打电话 那我有两种方式 一种就是一个在那等 阻塞着,一种就是 下去抽根烟一会再回来 如果打完了就问打不完继续干自己的事 再回来看 一直循环

手写自旋锁

SpinLockDemo 示例

大致思路: 通过CAS操作完成自旋锁 -- A线程先进来调用myLock方法自己持有5秒钟 -- B进来后发现当前线程持有锁不为空 --
          只能通过自旋等待 -- 直到A释放锁后B随即抢到

独占锁(写)/共享锁(读)/互斥锁/读写锁

独占锁:指该锁一次只能被一个线程所持有。对ReentrantLock和Synchronized而言都是独占锁

共享锁:指该锁可被多个线程所持有

对ReentrantReadWriteLock其读锁是共享锁,其写锁是独占锁

读锁的共享可保证并发读是非常高效的,读写,写读,写写的过程是互斥的

ReadWriteLockDemo 模拟操作缓存类