Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 7 additions & 11 deletions cdm/core/src/main/java/ucar/nc2/StringLocker.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package ucar.nc2;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.*;
import java.util.concurrent.ConcurrentSkipListSet;

/**
* A list of strings that only allows one thread to use any given value at the same time.
Expand All @@ -13,32 +12,29 @@
@Deprecated
public class StringLocker {

private List<String> stringList = Collections.synchronizedList(new ArrayList<>());
private boolean waiting;
private final Set<String> stringSet = new ConcurrentSkipListSet<>();

public synchronized void control(String item) {
// If the string is in use by another thread then wait() for the other thread
waiting = stringList.contains(item);
while (waiting) {
while (stringSet.contains(item)) {
try {
wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
// Finished waiting so the thread can have the string
stringList.add(item);
stringSet.add(item);
}

public synchronized void release(String item) {
// Tell StringLocker the thread is done with the string
stringList.remove(item);
waiting = false;
stringSet.remove(item);
notifyAll();
}

public String toString() {
return stringList.toString();
return stringSet.toString();
}

}
46 changes: 46 additions & 0 deletions cdm/core/src/test/java/ucar/nc2/StringLockerTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package ucar.nc2;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runners.model.TestTimedOutException;

public class StringLockerTest {
@Test
public void testNonconflicting() {
StringLocker locker = new StringLocker();
locker.control("first");
locker.control("second");
locker.release("first");
locker.release("second");
}


@Test
public void testConflicting() {
Thread t = new Thread(() -> {
StringLocker locker = new StringLocker();
locker.control("first");
locker.control("second");
locker.release("second");
locker.control("first");
Assert.fail("first has been locked twice");
});
t.start();
try {
t.join(50l);
} catch (InterruptedException e) {
// try to abort.
t.interrupt();
// pass
}
}

@Test
public void testNonconflictingOtherOrder() {
StringLocker locker = new StringLocker();
locker.control("first");
locker.control("second");
locker.release("second");
locker.release("first");
}
}