@Slf4j
public class TestLock {
public static void main(String[] args) throws Exception{
ReentrantLock lock = new ReentrantLock(false);
String mainThreadName = Thread.currentThread().getName();
System.out.println("=====BEGIN=====");
try {
new Thread(() -> {
String name = Thread.currentThread().getName();
lock.lock(); // 第一次加锁
System.out.println("1-1、"+lock.tryLock()); // 第二次加锁
System.out.println("1-2、"+lock.tryLock()); // 第三次加锁
Thread.currentThread().setName("线程A");
// 未解锁前,剩余锁数量:3
lock.unlock(); // 解锁,剩余锁数量:2
lock.unlock(); // 解锁,剩余锁数量:1
lock.unlock(); // 解锁,剩余锁数量:0
System.out.println(name + " lock.getHoldCount: " + lock.getHoldCount()); // 打印:0
}).start();
new Thread(() -> {
String name = Thread.currentThread().getName();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("2、"+lock.tryLock());
Thread.currentThread().setName("线程B");
//System.out.println(name);
if (lock.isLocked()) {
System.out.println(name + " =1= lock.getHoldCount: " + lock.getHoldCount());
System.out.println(name+"解锁");
lock.unlock();
System.out.println(name + " =2= lock.getHoldCount: " + lock.getHoldCount());
}
}).start();
new Thread(() -> {
String name = Thread.currentThread().getName();
try {
Thread.sleep(200); // 睡眠时间与线程B相同,下面lock.unlock()会报IllegalMonitorStateException
// Thread.sleep(400); // lock.unlock()不会报IllegalMonitorStateException
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("3、"+lock.tryLock());
Thread.currentThread().setName("线程C");
if (lock.isLocked()) {
// 因为睡眠时间相同,所以可能出现的情况:线程B获取到锁但还未解锁,再结合lock.isLocked()源码(any thread),
// 即锁还未被释放,进入判断后lock.unlock()失败,因为不符合:If the current thread is the holder of this lock
System.out.println(name+"解锁");
lock.unlock();
}
}).start();
} catch (Exception e) {
log.error(e.getMessage(),e);
}
System.out.println(mainThreadName+" lock.isLocked: " + lock.isLocked());
System.out.println("=====END=====");
}
}