Java锁之可重入锁和递归锁
目录
- Java锁之可重入锁和递归锁基本概念
- Java锁之可重入锁和递归锁代码验证
- 小结
理论,代码,小结,学习三板斧。
1. Java锁之可重入锁和递归锁基本概念
- 可重入锁(也叫递归锁),指的是同一线程外层函数获得锁之后,内层递归函数仍然能获取该锁的代码,在同一个线程在外层方法获取锁的时候,在进入内层方法会自动获取锁,也即是说,
线程可以进入任何一个它己经拥有的锁所同步着的代码块
。 - 现在会有点迷,看下面代码验证就会明白
2. Java锁之可重入锁和递归锁代码验证
代码:
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class Phone implements Runnable {
public synchronized void sendSMS() throws Exception {
System.out.println(Thread.currentThread().getId() + "\t invoked sendSMS()");
sendEmail();
}
public synchronized void sendEmail() throws Exception {
System.out.println(Thread.currentThread().getId() + "\t #####invoked sendEmail()");
}
Lock lock = new ReentrantLock();
@Override
public void run() {
get();
}
private void get() {
lock.lock();
try {
//线程可以进入任何一个它已经拥有的锁所同步的代码块
System.out.println(Thread.currentThread().getId() + "\t invoked get()");
set();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
private void set() {
lock.lock();
try {
System.out.println(Thread.currentThread().getId() + "\t #####invoked set()");
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
public class ReenterLockDemo {
public static void main(String[] args) {
Phone phone = new Phone();
new Thread(() -> {
try {
phone.sendSMS();
} catch (Exception e) {
e.printStackTrace();
}
}, "t1").start();
new Thread(() -> {
try {
phone.sendSMS();
} catch (Exception e) {
e.printStackTrace();
}
}, "t2").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println();
System.out.println();
System.out.println();
Thread t3 = new Thread(phone, "t3");
Thread t4 = new Thread(phone, "t4");
t3.start();
t4.start();
}
}
编译结果:
3. 小结
- 通过上面代码可以知道,synchronized和ReentrantLock都是典型的可重入锁。
- 拿其中一个结果分析:
- 再看看概念:可重入锁(也叫递归锁),指的是同一线程外层函数获得锁之后,内层递归函数仍然能获取该锁的代码,在同一个线程在外层方法获取锁的时候,在进入内层方法会自动获取锁,也即是说,
线程可以进入任何一个它己经拥有的锁所同步着的代码块
。