public synchronized boolean tryLock() throws IOException {
        LOGGER.trace("Acquiring lock on {}", file.getAbsolutePath());
        try {
            // weirdly this method will return null if the lock is held by another
            // process, but will throw an exception if the lock is held by this process
            // so we have to handle both cases
            flock = channel.tryLock();
            return flock != null;
        } catch (OverlappingFileLockException e) {
            return false;
        }
    }
@Test
    void testTryLock() throws IOException {
        File tempFile = TestUtils.tempFile();
        FileLock lock1 = new FileLock(tempFile);
        try {
            assertTrue(lock1.tryLock());
            assertFalse(lock1.tryLock());

            FileLock lock2 = new FileLock(tempFile);
            assertFalse(lock2.tryLock());
            assertThrows(OverlappingFileLockException.class, lock2::lock);
            lock1.unlock();
        } finally {
            lock1.destroy();
        }
    }