可重入锁
可重⼊锁(⼜名递归锁)
是指在同⼀个线程在外层⽅法获取锁的时候,再进⼊该线程的内层⽅法会⾃动获取锁(前提,锁对象得是同⼀个对象),不会因为之前已经获取过还没释放⽽阻塞。
如果是1个有 synchronized 修饰的递归调⽤⽅法,程序第2次进⼊被⾃⼰阻塞了岂不是天⼤的笑话,出现了作茧⾃缚。所以Java中ReentrantLock和synchronized都是可重⼊锁,可重⼊锁的⼀个优点是可⼀定程度避免死锁。
同步块
1、“可重⼊锁”这四个字分开来解释:
2、可重⼊锁种类
1、隐式锁(即synchronized关键字使⽤的锁)默认是可重⼊锁
指的是可重复可递归调⽤的锁,在外层使⽤锁之后,在内层仍然可以使⽤,并且不发⽣死锁,这样的锁
就叫做可重⼊锁。
简单的来说就是:在⼀个synchronized修饰的⽅法或代码块的内部调⽤本类的其他synchronized
修饰的⽅法或代码块时,是永远可以得到锁的
与可重⼊锁相反,不可重⼊锁不可递归调⽤,递归调⽤就发⽣死锁。
可:可以。
重:再次。
⼊:进⼊。
锁:同步锁。
进⼊什么:进⼊同步域(即同步代码块/⽅法或显式锁锁定的代码)
⼀句话:⼀个线程中的多个流程可以获取同⼀把锁,持有这把同步锁可以再次进⼊。
⾃⼰可以获取⾃⼰的内部锁
2.显式锁(即Lock)也有ReentrantLock这样的可重⼊锁。
public class Demo4 {
private static int num = 0;
private static ReentrantLock lock = new ReentrantLock();
private static void add() {
lock.lock();
lock.lock();
try {
num++;
} finally {
lock.unlock();
lock.unlock();
}
}
public static class T extends Thread {
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
Demo4.add();
}
}
}
public static void main(String[] args) throws InterruptedException {
T t1 = new T();
T t2 = new T();
T t3 = new T();
t1.start();
t2.start();
t3.start();
t1.join();
t2.join();
t3.join();
System.out.println(Demo4.num);
}
}