公平、非公平锁和可重入锁

公平锁和非公平锁区别

  1. 公平锁:大家老老实实排队,先来后到,等待队列按照FIFO规则获取锁。
  2. 非公平锁:抢占资源,多线程获取锁的顺序不按照申请锁的顺序;在高并发情况下,有可能会造成优先级反转或饥饿现象;优点在于性能比公平锁大。

如何得到公平/非公平锁?

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

ReentrantLock默认是非公平锁;synchronized也是非公平锁。

可重入锁(又名递归锁)

可重入锁,也叫做递归锁,指的是同一线程外层函数获得锁之后,内层递归函数仍然能获取该锁的代码,在同一线程在外层方法获取锁的时候,在进入内层方法会自动获取锁,也就是说线程可以进入任何一个他已经拥有的锁所同步着的代码块;当一个线程请求得到一个对象锁后再次请求此对象锁,可以再次得到该对象锁。

ReentrantLock内部只有一个成员变量Sync,作为一个核心内部类,绝大部分方法都直接依赖这个类实现。

Sync是AQS[AbstractQueuedSynchronizer]的抽象子类

ReentrantLock和sync是典型的可重入锁;ReentrantLock在重入时要却确保重复获取锁的次数必须和重复释放锁的次数一样,否则可能导致其他线程无法获得该锁。

可重入锁的最大作用是避免死锁。

Lock lock = new ReentrantLock();
public void get() {
        lock.lock();
        System.out.println(Thread.currentThread().getId());
        set();
        lock.unlock();
    }

public void set() {
        lock.lock();
        System.out.println(Thread.currentThread().getId());
        lock.unlock();
}

调用 get() 方法,同一个线程 ID 会被连续输出两次。

posted @ 2019-09-03 14:12  要好好吃饭  阅读(277)  评论(0编辑  收藏  举报