公平和非公平锁
- 公平锁:是指多个线程按照申请的顺序来获取值
- 非公平锁:是值多个线程获取值的顺序并不是按照申请锁的顺序,有可能后申请的线程比先申请的线程优先获取锁,在高并发的情况下,可能会造成优先级翻转或者饥饿现象
- 公平锁:在并发环境中,每一个线程在获取锁时会先查看此锁维护的等待队列,如果为空,或者当前线程是等待队列的第一个就占有锁,否则就会加入到等待队列中,以后会按照 FIFO 的规则获取锁
- 非公平锁:一上来就尝试占有锁,如果失败在进行排队
可重入锁和不可重入锁
- 可重入锁:指的是同一个线程外层函数获得锁之后,内层仍然能获取到该锁,在同一个线程在外层方法获取锁的时候,在进入内层方法或会自动获取该锁
- 不可重入锁: 所谓不可重入锁,即若当前线程执行某个方法已经获取了该锁,那么在方法中尝试再次获取锁时,就会获取不到被阻塞
- 可重入锁(JDK提供的所有现成的Lock实现类,包括synchronized关键字锁都是可重入的。)
自旋锁(SpinLockDemo.class)
- 是指定尝试获取锁的线程不会立即堵塞,而是采用循环的方式去尝试获取锁,这样的好处是减少线程上线文切换的消耗,缺点就是循环会消耗 CPU。
CAS也是一个自旋等待算法
public void lock(AtomicReference atomicReference) {
//循环等待
while (!atomicReference.compareAndSet(null, Thread.currentThread())) {
}
System.out.println("线程" + Thread.currentThread().getName() + "获取锁");
}
public void unlock(AtomicReference atomicReference) {
atomicReference.compareAndSet(Thread.currentThread(), null);
System.out.println("线程" + Thread.currentThread().getName() + "释放锁");
}