【Lock】加锁解锁


@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=====");

    }
}