1、锁

1.1、公平锁与非公平锁

  • 公平fair锁:遵守FIFS,先来先服务,按照线程的申请顺序
  • 非公平Nofair:多个线程获取锁的顺序不是严格按照申请的顺序,存在插队现象,在高并发的环境下,可能造成优先级反转或者饥饿现象,synchronized是一种非公平锁
public ReentrantLock() {
// 默认非公平锁
sync = new NonfairSync();
}

公平锁的先来先服务,保证公平,同样也是致命的问题。
比如买咖啡时,你买一杯,你前面那位买99杯,你的体验会特别的糟糕,现实中,你可以与前面的人商量让店员先给你做,然而公平锁是不允许这样交换的,就是先来先得。

1.2、可重入锁(递归锁)

指的是同一线程外层函数获得锁之后,内层递归函数仍然能够获取该锁的代码
同一个线程在外层方法获取锁的时候,在进入内层方法会自动获取锁。
也就是说,线程可以进入任何一个它已经拥有的锁所同步着的代码块
同步方法1内部调用同步方法2,当线程获取同步方法1的锁,它也会获取方法2的锁。Synchronized和ReentrantLock是典型的可重入锁,可重入锁最大的作用是避免死锁

1.3、独占锁(写锁)、共享锁(读锁)

独占锁:只能被一个线程占用,对ReentrantLock和Synchronized而言都是独占锁
共享锁:可以被多个线程所持有
对ReentrantReadWriteLock而言,读锁为共享,写锁为独占锁
读锁的共享锁可以保证并发读时非常高效的,读写、写写的过程是互斥

1.4、自旋锁

是指尝试获取的线程不会立即阻塞,而是采用循环的方式去尝试获取锁,这样的好处就是减少线程上下文切换的消耗,缺点是循环会消耗CPU