【面试题】公平锁和非公平锁、可重入锁

  • 1. 公平锁和非公平锁
    • 1.1 是什么
    • 1.2 两者区别
  • 2. 可重入锁(递归锁)
    • 2.1 可重入锁有哪些
    • 2.2 可重入锁作用
    • 2.3 可重入锁demo --synchronized
    • 2.4 可重入锁demo --ReentrantLock

1. 公平锁和非公平锁

1.1 是什么

公平锁 :按照线程在队列中的排队顺序,先到者先拿到锁
非公平锁 :当线程要获取锁时,先通过两次 CAS 操作去抢锁,如果没抢到,当前线程再加入到队列中等待唤醒。

1.2 两者区别

非公平锁在调用 lock 后,首先就会调用 CAS 进行一次抢锁,如果这个时候恰巧锁没有被占用,那么直接就获取到锁返回了。
非公平锁在 CAS 失败后,和公平锁一样都会进入到 tryAcquire 方法,在 tryAcquire 方法中,如果发现锁这个时候被释放了(state == 0),非公平锁会直接 CAS 抢锁,但是公平锁会判断等待队列是否有线程处于等待状态,如果有则不去抢锁,乖乖排到后面。

公平锁和非公平锁就这两点区别,如果这两次 CAS 都不成功,那么后面非公平锁和公平锁是一样的,都要进入到阻塞队列等待唤醒。

2. 可重入锁(递归锁)

同一线程,在外层方法获取锁后,内层方法自动获取锁。也就是说,线程可以进入任何一个他已经拥有锁同步的方法。

public synchronized void  method1(){
   method2();
}
public synchronized void  method2(){

}

2.1 可重入锁有哪些

ReentrantLock/synchronized

2.2 可重入锁作用

避免死锁。

2.3 可重入锁demo --synchronized

class Phone {
    synchronized void  sendSMS(){
        System.out.println(Thread.currentThread().getName()+"---sendSMS");
        sendEmail();
    }
    synchronized void sendEmail(){
        System.out.println(Thread.currentThread().getName()+"---sendEmail");
    }
}
public class TestArrayList {

    public static void main(String[] args) {
        Phone phone = new Phone();

        new Thread(()->{
            phone.sendSMS();
        },"t1").start();

        new Thread(()->{
            phone.sendSMS();
        },"t2").start();
    }
}

在这里插入图片描述

2.4 可重入锁demo --ReentrantLock

class Phone implements Runnable {

    Lock lock = new ReentrantLock();

    @Override
    public void run() {
        method1();
    }

    void method1() {
        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName() + "--method1--lock");
            method2();
        } finally {
            lock.unlock();
            System.out.println(Thread.currentThread().getName() + "--method1--unlock");
        }
    }

    void method2() {
        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName() + "--method2--lock");
        } finally {
            lock.unlock();
            System.out.println(Thread.currentThread().getName() + "--method2--unlock");
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Phone phone = new Phone();
        Thread t1 = new Thread(phone, "t1");
        Thread t2 = new Thread(phone, "t2");
        t1.start();
        t2.start();
    }
}

在这里插入图片描述

你可能感兴趣的:(面试题-并发,java,面试)