【面试题】公平锁和非公平锁/可重入锁
锁
- 1. 公平锁和非公平锁
- 1.1 是什么
- 1.2 两者区别
- 2. 可重入锁(递归锁)
- 2.1 可重入锁有哪些
- 2.2 可重入锁作用
- 2.3 可重入锁demo --synchronized
- 2.4 可重入锁demo --ReentrantLock
1. 公平锁和非公平锁
1.1 是什么
公平锁:
多个线程按着申请锁的顺序来获取锁(类似排队,先来后到)。
非公平锁:
多个线程并非按着申请锁的顺序来获取锁,有可能后申请的线程更早获得锁,有可能会造成优先级反转。
1.2 两者区别
公平锁,在并发环境中,每个线程获取锁的时候会优先查询此锁维护的等待队列,如果为空或者自己是等待队列的第一个直接占有锁,否则加入等待队列。
非公平锁,上来就尝试占有锁,如果尝试失败,再采用类似公平锁的方式。
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();
}
}