什么是可重入锁和可重入函数
- ReentrantLock翻译过来就是可重入锁
- 所谓可重入锁,顾名思义,指的是线程可以重复获取同一把锁。
- 可重入函数:所谓可重入函数,指的是多个线程可以同时调用该函数,每个线程都能得到正确结果;同时在一个线程内支持线程切换,无论被切换多少次,结果都是正确的。
- 可重入锁只需要手动释放一次锁即可,其他情况都是由编译器进行隐式释放的
- 多线程可以同时执行,还支持线程切换,这意味着线程安全。
公平锁与非公平锁
- 在使用 ReentrantLock 时,会发现 ReentrantLock 这个类有两个构造函数,
- 一个是无参构造函数,一个是传入 fair 参数的构造函数。
- fair 参数代表的是锁的公平策略,如果传入 true 就表示需要构造一个公平锁,反之则表示要构造一个非公平锁。
- 入口等待队列,锁都对应着一个等待队列,如果一个线程没有获得锁,就会进入等待队列,当有线程释放锁的时候,就需要从等待队列中唤醒一个等待的线程。
- 如果是公平锁,唤醒的策略就是谁等待的时间长,就唤醒谁,很公平;
- 如果是非公平锁,则不提供这个公平保证,有可能等待时间短的线程反而先被唤醒。
用锁的最佳实践
- 永远只在更新对象的成员变量时加锁
- 永远只在访问可变的成员变量时加锁
- 永远不在调用其他对象的方法时加锁
- 减少锁的持有时间、减小锁的粒度
synchronized和Lock的区别
- lock支持中断响应
- lock支持超时返回
- lock支持非阻塞获取锁
- lock配合Condition可以支持多个管程中的条件变量(synchronized只支持一个)