Java 可重入锁 & 不可重入锁
概述
- 可重入锁:指可以重复使用的同步锁。如:synchronized、Lock、ReentrantReadWriteLock.ReadLock、ReentrantReadWriteLock.WriteLock。
- 不可重入锁:指不可以重复使用的同步锁。需要自定义锁。
论证synchronized是可重入锁:
public class Demo {
public static void main(String[] args) {
synchronized (Demo.class) {
System.out.println("第一次获取锁");
synchronized (Demo.class) {
System.out.println("第二次获取锁");
}
}
}
}
输出:
第一次获取锁
第二次获取锁
论证Lock是可重入锁:
public class Demo {
public static void main(String[] args) {
Lock lock = new ReentrantLock();
lock.lock();
try {
System.out.println("第一次获取锁");
lock.lock();
try {
System.out.println("第二次获取锁");
} finally {
lock.unlock();
}
} finally {
lock.unlock();
}
}
}
输出:
第一次获取锁
第二次获取锁
自定义不可重入锁:
public class Demo {
public static void main(String[] args) {
MyLock lock = new MyLock();
lock.lock();
try {
System.out.println("第一次获取锁");
lock.lock();
try {
System.out.println("第二次获取锁");
} finally {
lock.unlock();
}
} finally {
lock.unlock();
}
}
}
class MyLock implements Lock {
//绑定线程
private Thread thread;
@Override
public void lock() {
synchronized (this) {
while (thread != null) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.thread = Thread.currentThread();
}
}
@Override
public void lockInterruptibly() throws InterruptedException {
}
@Override
public boolean tryLock() {
return false;
}
@Override
public boolean tryLock(long l, TimeUnit timeUnit) throws InterruptedException {
return false;
}
@Override
public void unlock() {
synchronized (this) {
if (thread != Thread.currentThread()) {
return;
}
thread = null;
notifyAll();
}
}
@Override
public Condition newCondition() {
return null;
}
}
输出:
第一次获取锁
说明:只输出了一个打印信息,程序就进入等待阶段。