- 公平锁:公平锁就是保障了多线程下各线程获取锁的顺序、绝对时间上一定可以获取到锁。
非公平锁:非公平锁有饥饿现象,效率比公平锁高(cpu分时、无上下文切换开销)
悲观锁:假设一定会发生并发冲突,通过阻塞其他所有线程来保证数据的完整性。如,synchronized。【适用于数据争用不严重/重试代价不大/需要相应速度快的场景】
乐观锁:假设不会发生并发冲突,直接不加锁去完成某项更新,如果冲突就返回失败。如,CAS。【适用于数据争用严重/重试代价大的场景】
共享锁:对数据A加上共享锁之后只能再加上共享锁(如,读锁)
排他锁:对数据A加上排他锁之后不能再加上任何锁(如,写锁)
重入锁:当一个线程获取对象锁之后,这个线程可以再次获取本对象上的锁。【可以防止死锁】
- 读写锁:同一时刻允许多个读线程访问,但写线程访问并取得锁之后,其它线程均被阻塞。
- 自旋锁:当一个线程在获取锁的时候,如果锁已经被其它线程获取,那么该线程将循环等待,然后不断的判断锁是否能够被成功获取,直到获取到锁才会退出循环。【将一直处于用户态,无上下文切换代价】
- 偏向锁:当一个线程访问同步块时,会在对象头和站帧中的锁记录中记录锁偏向的线程ID,以后该线程进出同步块时不再需要CAS。换句话说:如果程序没有竞争,则取消之前获得了锁的线程的同步。
- 轻量级锁:如果偏向锁失败,线程申请轻量级锁
BasicObjectLock
,放在栈帧中。判断时只需判断对象头指针是否在当前线程的栈地址范围内。 - 锁粒度:如
ConcurrentHashMap
的实现,对不同的数据区进行加锁。 - 锁分离:如
LinkedBlockingQueue
的实现,对take()
和put()
这两个操作区间不同的操作进行不同的锁的分配。 - 锁粗化:把多次操作合并成一次对锁的申请。
同步队列、CLH和MSC:
https://www.jianshu.com/p/1b1b44e84394
https://www.jianshu.com/p/824b2e4f1eed
synchronized:阻塞式同步、悲观锁、非公平锁、重入锁。
volatile:无原子性,但对单个变量的读写具有原子性,如a=1
;可见性(缓存一致性原则);有序性(对一个volatile域的写,happens-before于任意后续对这个volatile域的读)。内存屏障见附图:
**