Skip to content

Commit 5894d9b

Browse files
committed
doc/test: KeyLock getter and fix write-exclusion test
1 parent be3fafb commit 5894d9b

2 files changed

Lines changed: 30 additions & 7 deletions

File tree

src/main/java/org/janelia/saalfeldlab/n5/KeyLock.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,24 @@ public boolean removeLockIfUnused(String key) {
140140
return false;
141141
}
142142

143+
/**
144+
* Returns an {@link Optional} containing the lock for the given
145+
* key, if it exists.
146+
* <p>
147+
* This method can be useful for monitoring and debugging. For example,
148+
* to check how many threads are currently reading a key:
149+
* <pre>{@code
150+
* keyLock.getKeyLock("myKey").ifPresent(lock -> {
151+
* System.out.println("Key 'myKey' has " + lock.getReadLockCount() + " readers");
152+
* });
153+
* }</pre>
154+
*
155+
* @param key
156+
* the key whose lock will be returned
157+
* @return an {@link Optional} containing the {@link ReentrantReadWriteLock}
158+
* for the key, or empty if no lock exists for the key
159+
*/
143160
public Optional<ReentrantReadWriteLock> getKeyLock(String key) {
144-
// TODO doc me
145161
return Optional.ofNullable(locks.get(key));
146162
}
147163

src/test/java/org/janelia/saalfeldlab/n5/KeyLockTest.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import java.util.concurrent.Executors;
3939
import java.util.concurrent.TimeUnit;
4040
import java.util.concurrent.atomic.AtomicInteger;
41+
import java.util.concurrent.atomic.AtomicReference;
4142
import java.util.concurrent.locks.Lock;
4243

4344
import org.junit.Test;
@@ -118,8 +119,7 @@ public void testConcurrentReads() throws InterruptedException {
118119
// With ReentrantReadWriteLock, we should see true concurrent reads
119120
assertTrue("Multiple readers should have been reading concurrently", maxConcurrentReaders.get() > 1);
120121

121-
// Time should be much less than sequential execution (numReaders *
122-
// 100ms)
122+
// Time should be much less than sequential execution (numReaders * 100ms)
123123
assertTrue("Concurrent execution should be faster than sequential", duration < numReaders * 100);
124124
}
125125

@@ -162,7 +162,7 @@ public void testReadWriteExclusion() throws InterruptedException {
162162
}
163163

164164
@Test
165-
public void testTryLock() {
165+
public void testTryLock() throws InterruptedException {
166166

167167
KeyLock keyLock = new KeyLock();
168168
String testKey = "test-key";
@@ -187,9 +187,16 @@ public void testTryLock() {
187187
writeLock = keyLock.tryLockForWriting(testKey);
188188
assertNotNull("Should acquire write lock after reads are released", writeLock);
189189

190-
// // Try acquiring read lock while write is held - should fail
191-
// Lock readLock3 = keyLock.tryLockForReading(testKey);
192-
// assertNull("Should not acquire read lock while write is held", readLock3);
190+
// Try acquiring read lock from another thread while write is held - should fail
191+
// Because
192+
AtomicReference<Lock> readLock3 = new AtomicReference<>();
193+
Thread readerThread = new Thread(() -> {
194+
readLock3.set(keyLock.tryLockForReading(testKey));
195+
});
196+
readerThread.start();
197+
readerThread.join();
198+
199+
assertNull("Should not acquire read lock while write is held", readLock3.get());
193200

194201
writeLock.unlock();
195202
}

0 commit comments

Comments
 (0)