private void distributedLockTest(RheaKVStore store) throws InterruptedException {
        // regions: 1 -> [null, g), 2 -> [g, null)
        byte[] lockKey = makeKey("lock_test");
        checkRegion(store, lockKey, 2);
        final DistributedLock<byte[]> lock = store.getDistributedLock(lockKey, 3, TimeUnit.SECONDS);
        assertNotNull(lock);
        assertTrue(lock.tryLock()); // can lock
        assertTrue(lock.tryLock()); // reentrant lock
        final CountDownLatch latch1 = new CountDownLatch(1);
        Thread t = new Thread(() -> {
            final DistributedLock<byte[]> lock1 = store.getDistributedLock(lockKey, 3, TimeUnit.SECONDS);
            try {
                assertTrue(!lock1.tryLock()); // fail to lock
            } finally {
                latch1.countDown();
            }
        }, "locker1-thread");
        t.setDaemon(true);
        t.start();
        latch1.await();
        final CountDownLatch latch2 = new CountDownLatch(1);
        t = new Thread(() -> {
            final DistributedLock<byte[]> lock2 = store.getDistributedLock(lockKey, 3, TimeUnit.SECONDS);
            try {
                // Waiting for the lock to expire and lock successfully
                assertTrue(lock2.tryLock(3100, TimeUnit.MILLISECONDS));
            } finally {
                lock2.unlock();
                latch2.countDown();
            }
        }, "locker2-thread");
        t.setDaemon(true);
        t.start();
        latch2.await();

        assertTrue(lock.tryLock());
        assertTrue(lock.tryLock());
        assertTrue(lock.tryLock());
        lock.unlock();
        final CountDownLatch latch3 = new CountDownLatch(1);
        t = new Thread(() -> {
            final DistributedLock<byte[]> lock3 = store.getDistributedLock(lockKey, 3, TimeUnit.SECONDS);
            try {
                // The previous lock was not released and the lock failed.
                assertTrue(!lock3.tryLock());
            } finally {
                latch3.countDown();
            }
        }, "locker3-thread");
        t.setDaemon(true);
        t.start();
        latch3.await();

        lock.unlock();
        lock.unlock();
        final CountDownLatch latch4 = new CountDownLatch(1);
        t = new Thread(() -> {
            final DistributedLock<byte[]> lock4 = store.getDistributedLock(lockKey, 3, TimeUnit.SECONDS);
            try {
                assertTrue(lock4.tryLock()); // lock success
            } finally {
                lock4.unlock();
                latch4.countDown();
            }
        }, "locker4-thread");
        t.setDaemon(true);
        t.start();
        latch4.await();

        // lock with lease scheduler
        final ScheduledExecutorService watchdog = Executors.newScheduledThreadPool(1);
        final DistributedLock<byte[]> lockWithScheduler = store.getDistributedLock(lockKey, 3, TimeUnit.SECONDS,
                watchdog);
        lockWithScheduler.tryLock();
        Thread.sleep(5000);

        final CountDownLatch latch5 = new CountDownLatch(1);
        t = new Thread(() -> {
            final DistributedLock<byte[]> lock5 = store.getDistributedLock(lockKey, 3, TimeUnit.SECONDS);
            try {
                // Locking failed because lockWithScheduler is renewing
                assertTrue(!lock5.tryLock());
            } finally {
                latch5.countDown();
            }
        }, "locker5-thread");
        t.setDaemon(true);
        t.start();
        latch5.await();

        lockWithScheduler.unlock();

        final CountDownLatch latch6 = new CountDownLatch(1);
        t = new Thread(() -> {
            final DistributedLock<byte[]> lock6 = store.getDistributedLock(lockKey, 3, TimeUnit.SECONDS);
            try {
                assertTrue(lock6.tryLock()); // lock success
            } finally {
                lock6.unlock();
                latch6.countDown();
            }
        }, "locker6-thread");
        t.setDaemon(true);
        t.start();
        latch6.await();
    }
Test method: {@link RheaKVStore#getDistributedLock(byte[], long, TimeUnit)}
jraft-rheakv/rheakv-core/src/test/java/com/alipay/sofa/jraft/rhea/storage/rhea/AbstractRheaKVStoreTest.java