Correctly release threads from starting gate in o.e.c.c.CacheTests
This commit is contained in:
parent
0a816cd343
commit
35cc749c9a
|
@ -494,15 +494,22 @@ public class CacheTests extends ESTestCase {
|
||||||
public void testComputeIfAbsentCallsOnce() throws InterruptedException {
|
public void testComputeIfAbsentCallsOnce() throws InterruptedException {
|
||||||
int numberOfThreads = randomIntBetween(2, 32);
|
int numberOfThreads = randomIntBetween(2, 32);
|
||||||
final Cache<Integer, String> cache = CacheBuilder.<Integer, String>builder().build();
|
final Cache<Integer, String> cache = CacheBuilder.<Integer, String>builder().build();
|
||||||
List<Thread> threads = new ArrayList<>();
|
|
||||||
AtomicReferenceArray flags = new AtomicReferenceArray(numberOfEntries);
|
AtomicReferenceArray flags = new AtomicReferenceArray(numberOfEntries);
|
||||||
for (int j = 0; j < numberOfEntries; j++) {
|
for (int j = 0; j < numberOfEntries; j++) {
|
||||||
flags.set(j, false);
|
flags.set(j, false);
|
||||||
}
|
}
|
||||||
CountDownLatch latch = new CountDownLatch(1 + numberOfThreads);
|
CountDownLatch startGate = new CountDownLatch(1);
|
||||||
|
CountDownLatch endGate = new CountDownLatch(numberOfThreads);
|
||||||
|
AtomicBoolean interrupted = new AtomicBoolean();
|
||||||
for (int i = 0; i < numberOfThreads; i++) {
|
for (int i = 0; i < numberOfThreads; i++) {
|
||||||
Thread thread = new Thread(() -> {
|
Thread thread = new Thread(() -> {
|
||||||
latch.countDown();
|
try {
|
||||||
|
try {
|
||||||
|
startGate.await();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
interrupted.set(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
for (int j = 0; j < numberOfEntries; j++) {
|
for (int j = 0; j < numberOfEntries; j++) {
|
||||||
try {
|
try {
|
||||||
cache.computeIfAbsent(j, key -> {
|
cache.computeIfAbsent(j, key -> {
|
||||||
|
@ -513,14 +520,15 @@ public class CacheTests extends ESTestCase {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
endGate.countDown();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
threads.add(thread);
|
|
||||||
thread.start();
|
thread.start();
|
||||||
}
|
}
|
||||||
latch.countDown();
|
startGate.countDown();
|
||||||
for (Thread thread : threads) {
|
endGate.await();
|
||||||
thread.join();
|
assertFalse(interrupted.get());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testComputeIfAbsentThrowsExceptionIfLoaderReturnsANullValue() {
|
public void testComputeIfAbsentThrowsExceptionIfLoaderReturnsANullValue() {
|
||||||
|
@ -560,13 +568,20 @@ public class CacheTests extends ESTestCase {
|
||||||
|
|
||||||
int numberOfThreads = randomIntBetween(2, 32);
|
int numberOfThreads = randomIntBetween(2, 32);
|
||||||
final Cache<Key, Integer> cache = CacheBuilder.<Key, Integer>builder().build();
|
final Cache<Key, Integer> cache = CacheBuilder.<Key, Integer>builder().build();
|
||||||
CountDownLatch latch = new CountDownLatch(1 + numberOfThreads);
|
CountDownLatch startGate = new CountDownLatch(1);
|
||||||
CountDownLatch deadlockLatch = new CountDownLatch(numberOfThreads);
|
CountDownLatch deadlockLatch = new CountDownLatch(numberOfThreads);
|
||||||
|
AtomicBoolean interrupted = new AtomicBoolean();
|
||||||
List<Thread> threads = new ArrayList<>();
|
List<Thread> threads = new ArrayList<>();
|
||||||
for (int i = 0; i < numberOfThreads; i++) {
|
for (int i = 0; i < numberOfThreads; i++) {
|
||||||
Thread thread = new Thread(() -> {
|
Thread thread = new Thread(() -> {
|
||||||
|
try {
|
||||||
|
try {
|
||||||
|
startGate.await();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
interrupted.set(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
Random random = new Random(random().nextLong());
|
Random random = new Random(random().nextLong());
|
||||||
latch.countDown();
|
|
||||||
for (int j = 0; j < numberOfEntries; j++) {
|
for (int j = 0; j < numberOfEntries; j++) {
|
||||||
Key key = new Key(random.nextInt(numberOfEntries));
|
Key key = new Key(random.nextInt(numberOfEntries));
|
||||||
try {
|
try {
|
||||||
|
@ -582,8 +597,10 @@ public class CacheTests extends ESTestCase {
|
||||||
fail(e.getMessage());
|
fail(e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
// successfully avoided deadlock, release the main thread
|
// successfully avoided deadlock, release the main thread
|
||||||
deadlockLatch.countDown();
|
deadlockLatch.countDown();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
threads.add(thread);
|
threads.add(thread);
|
||||||
thread.start();
|
thread.start();
|
||||||
|
@ -614,7 +631,7 @@ public class CacheTests extends ESTestCase {
|
||||||
}, 1, 1, TimeUnit.SECONDS);
|
}, 1, 1, TimeUnit.SECONDS);
|
||||||
|
|
||||||
// everything is setup, release the hounds
|
// everything is setup, release the hounds
|
||||||
latch.countDown();
|
startGate.countDown();
|
||||||
|
|
||||||
// wait for either deadlock to be detected or the threads to terminate
|
// wait for either deadlock to be detected or the threads to terminate
|
||||||
deadlockLatch.await();
|
deadlockLatch.await();
|
||||||
|
@ -628,11 +645,18 @@ public class CacheTests extends ESTestCase {
|
||||||
public void testCachePollution() throws InterruptedException {
|
public void testCachePollution() throws InterruptedException {
|
||||||
int numberOfThreads = randomIntBetween(2, 32);
|
int numberOfThreads = randomIntBetween(2, 32);
|
||||||
final Cache<Integer, String> cache = CacheBuilder.<Integer, String>builder().build();
|
final Cache<Integer, String> cache = CacheBuilder.<Integer, String>builder().build();
|
||||||
CountDownLatch latch = new CountDownLatch(1 + numberOfThreads);
|
CountDownLatch startGate = new CountDownLatch(1);
|
||||||
List<Thread> threads = new ArrayList<>();
|
CountDownLatch endGate = new CountDownLatch(numberOfThreads);
|
||||||
|
AtomicBoolean interrupted = new AtomicBoolean();
|
||||||
for (int i = 0; i < numberOfThreads; i++) {
|
for (int i = 0; i < numberOfThreads; i++) {
|
||||||
Thread thread = new Thread(() -> {
|
Thread thread = new Thread(() -> {
|
||||||
latch.countDown();
|
try {
|
||||||
|
try {
|
||||||
|
startGate.await();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
interrupted.set(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
Random random = new Random(random().nextLong());
|
Random random = new Random(random().nextLong());
|
||||||
for (int j = 0; j < numberOfEntries; j++) {
|
for (int j = 0; j < numberOfEntries; j++) {
|
||||||
Integer key = random.nextInt(numberOfEntries);
|
Integer key = random.nextInt(numberOfEntries);
|
||||||
|
@ -662,15 +686,16 @@ public class CacheTests extends ESTestCase {
|
||||||
cache.get(key);
|
cache.get(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
endGate.countDown();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
threads.add(thread);
|
|
||||||
thread.start();
|
thread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
latch.countDown();
|
startGate.countDown();
|
||||||
for (Thread thread : threads) {
|
endGate.await();
|
||||||
thread.join();
|
assertFalse(interrupted.get());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// test that the cache is not corrupted under lots of concurrent modifications, even hitting the same key
|
// test that the cache is not corrupted under lots of concurrent modifications, even hitting the same key
|
||||||
|
@ -683,24 +708,33 @@ public class CacheTests extends ESTestCase {
|
||||||
.weigher((k, v) -> 2)
|
.weigher((k, v) -> 2)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
CountDownLatch latch = new CountDownLatch(1 + numberOfThreads);
|
CountDownLatch startGate = new CountDownLatch(1);
|
||||||
List<Thread> threads = new ArrayList<>();
|
CountDownLatch endGate = new CountDownLatch(numberOfThreads);
|
||||||
|
AtomicBoolean interrupted = new AtomicBoolean();
|
||||||
for (int i = 0; i < numberOfThreads; i++) {
|
for (int i = 0; i < numberOfThreads; i++) {
|
||||||
Thread thread = new Thread(() -> {
|
Thread thread = new Thread(() -> {
|
||||||
|
try {
|
||||||
|
try {
|
||||||
|
startGate.await();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
interrupted.set(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
Random random = new Random(random().nextLong());
|
Random random = new Random(random().nextLong());
|
||||||
latch.countDown();
|
|
||||||
for (int j = 0; j < numberOfEntries; j++) {
|
for (int j = 0; j < numberOfEntries; j++) {
|
||||||
Integer key = random.nextInt(numberOfEntries);
|
Integer key = random.nextInt(numberOfEntries);
|
||||||
cache.put(key, Integer.toString(j));
|
cache.put(key, Integer.toString(j));
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
endGate.countDown();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
threads.add(thread);
|
|
||||||
thread.start();
|
thread.start();
|
||||||
}
|
}
|
||||||
latch.countDown();
|
startGate.countDown();
|
||||||
for (Thread thread : threads) {
|
endGate.await();
|
||||||
thread.join();
|
assertFalse(interrupted.get());
|
||||||
}
|
|
||||||
cache.refresh();
|
cache.refresh();
|
||||||
assertEquals(500, cache.count());
|
assertEquals(500, cache.count());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue