### Question:
FileLock { public void decreaseLock(@NonNull String path) { AtomicInteger lockCount; synchronized (fileLockCountMap) { lockCount = fileLockCountMap.get(path); } if (lockCount != null && lockCount.decrementAndGet() == 0) { Util.d(TAG, "decreaseLock decrease lock-count to 0 " + path); final Thread lockedThread; synchronized (waitThreadForFileLockMap) { lockedThread = waitThreadForFileLockMap.get(path); if (lockedThread != null) { waitThreadForFileLockMap.remove(path); } } if (lockedThread != null) { Util.d(TAG, "decreaseLock " + path + " unpark locked thread " + lockCount); unpark(lockedThread); } synchronized (fileLockCountMap) { fileLockCountMap.remove(path); } } } FileLock(@NonNull Map<String, AtomicInteger> fileLockCountMap,
             @NonNull Map<String, Thread> waitThreadForFileLockMap);   FileLock(); void increaseLock(@NonNull String path); void decreaseLock(@NonNull String path); void waitForRelease(@NonNull String filePath);  }### Answer:
@Test public void decreaseLock() { waitThreadForFileLockMap.put(filePath1, lockedThread); fileLock.decreaseLock(filePath1); assertThat(fileLockCountMap.get(filePath1)).isNull(); fileLockCountMap.put(filePath1, new AtomicInteger(2)); fileLock.decreaseLock(filePath1); assertThat(fileLockCountMap.get(filePath1).get()).isOne(); fileLock.decreaseLock(filePath1); assertThat(fileLockCountMap.get(filePath1)).isNull(); verify(fileLock).unpark(eq(lockedThread)); assertThat(waitThreadForFileLockMap.isEmpty()).isTrue(); fileLock.decreaseLock(filePath2); assertThat(fileLockCountMap.get(filePath2)).isNull(); }