Skip to content

Commit c8ad1f7

Browse files
committed
Fix StringLocker behavior.
1 parent 4ca3c15 commit c8ad1f7

2 files changed

Lines changed: 53 additions & 11 deletions

File tree

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
package ucar.nc2;
22

3-
import java.util.ArrayList;
4-
import java.util.Collections;
5-
import java.util.List;
3+
import java.util.*;
4+
import java.util.concurrent.ConcurrentSkipListSet;
65

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

16-
private List<String> stringList = Collections.synchronizedList(new ArrayList<>());
17-
private boolean waiting;
15+
private final Set<String> stringSet = new ConcurrentSkipListSet<>();
1816

1917
public synchronized void control(String item) {
2018
// If the string is in use by another thread then wait() for the other thread
21-
waiting = stringList.contains(item);
22-
while (waiting) {
19+
while (stringSet.contains(item)) {
2320
try {
2421
wait();
2522
} catch (InterruptedException e) {
2623
Thread.currentThread().interrupt();
2724
}
2825
}
2926
// Finished waiting so the thread can have the string
30-
stringList.add(item);
27+
stringSet.add(item);
3128
}
3229

3330
public synchronized void release(String item) {
3431
// Tell StringLocker the thread is done with the string
35-
stringList.remove(item);
36-
waiting = false;
32+
stringSet.remove(item);
3733
notifyAll();
3834
}
3935

4036
public String toString() {
41-
return stringList.toString();
37+
return stringSet.toString();
4238
}
4339

4440
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package ucar.nc2;
2+
3+
import org.junit.Assert;
4+
import org.junit.Test;
5+
import org.junit.runners.model.TestTimedOutException;
6+
7+
public class StringLockerTest {
8+
@Test
9+
public void testNonconflicting() {
10+
StringLocker locker = new StringLocker();
11+
locker.control("first");
12+
locker.control("second");
13+
locker.release("first");
14+
locker.release("second");
15+
}
16+
17+
18+
@Test
19+
public void testConflicting() {
20+
Thread t = new Thread(() -> {
21+
StringLocker locker = new StringLocker();
22+
locker.control("first");
23+
locker.control("second");
24+
locker.release("second");
25+
locker.control("first");
26+
Assert.fail("first has been locked twice");
27+
});
28+
t.start();
29+
try {
30+
t.join(50l);
31+
} catch (InterruptedException e) {
32+
// try to abort.
33+
t.interrupt();
34+
// pass
35+
}
36+
}
37+
38+
@Test
39+
public void testNonconflictingOtherOrder() {
40+
StringLocker locker = new StringLocker();
41+
locker.control("first");
42+
locker.control("second");
43+
locker.release("second");
44+
locker.release("first");
45+
}
46+
}

0 commit comments

Comments
 (0)