aboutsummaryrefslogtreecommitdiffstats
path: root/vespajlib/src/test/java/com/yahoo/concurrent/ThreadRobustListTestCase.java
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
committerJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
commit72231250ed81e10d66bfe70701e64fa5fe50f712 (patch)
tree2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /vespajlib/src/test/java/com/yahoo/concurrent/ThreadRobustListTestCase.java
Publish
Diffstat (limited to 'vespajlib/src/test/java/com/yahoo/concurrent/ThreadRobustListTestCase.java')
-rw-r--r--vespajlib/src/test/java/com/yahoo/concurrent/ThreadRobustListTestCase.java103
1 files changed, 103 insertions, 0 deletions
diff --git a/vespajlib/src/test/java/com/yahoo/concurrent/ThreadRobustListTestCase.java b/vespajlib/src/test/java/com/yahoo/concurrent/ThreadRobustListTestCase.java
new file mode 100644
index 00000000000..88c7a962c95
--- /dev/null
+++ b/vespajlib/src/test/java/com/yahoo/concurrent/ThreadRobustListTestCase.java
@@ -0,0 +1,103 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.concurrent;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.fail;
+
+import java.util.Iterator;
+
+import org.junit.Test;
+
+/**
+ * Check we keep the consistent view when reading and writing in parallell.
+ *
+ * @author <a href="mailto:steinar@yahoo-inc.com">Steinar Knutsen</a>
+ */
+public class ThreadRobustListTestCase {
+
+ private static class Writer implements Runnable {
+ private final ThreadRobustList<String> l;
+ private final Receiver<Boolean> sharedLock;
+
+ public Writer(final ThreadRobustList<String> l,
+ final Receiver<Boolean> sharedLock) {
+ this.sharedLock = sharedLock;
+ this.l = l;
+ }
+
+ @Override
+ public void run() {
+ for (int i = 0; i < 5; ++i) {
+ l.add(String.valueOf(i));
+ }
+ sharedLock.put(Boolean.TRUE);
+ for (int i = 5; i < 100 * 1000; ++i) {
+ l.add(String.valueOf(i));
+ }
+ }
+
+ }
+
+ private static class Reader implements Runnable {
+ private final ThreadRobustList<String> l;
+ private final Receiver<Boolean> sharedLock;
+
+ public Reader(final ThreadRobustList<String> l,
+ final Receiver<Boolean> sharedLock) {
+ this.sharedLock = sharedLock;
+ this.l = l;
+ }
+
+ @Override
+ public void run() {
+ int n;
+ int previous;
+
+ try {
+ sharedLock.get(5 * 60 * 1000);
+ } catch (final InterruptedException e) {
+ fail("Test interrupted.");
+ }
+ n = countElements();
+ assertFalse(n < 5);
+ previous = n;
+ for (int i = 0; i < 1000; ++i) {
+ int reverse = reverseCountElements();
+ n = countElements();
+ assertFalse(n < reverse);
+ assertFalse(n < previous);
+ previous = n;
+ }
+ }
+
+ private int reverseCountElements() {
+ int n = 0;
+ for (final Iterator<String> j = l.reverseIterator(); j.hasNext(); j.next()) {
+ ++n;
+ }
+ return n;
+ }
+
+ private int countElements() {
+ int n = 0;
+ for (final Iterator<String> j = l.iterator(); j.hasNext(); j.next()) {
+ ++n;
+ }
+ return n;
+ }
+ }
+
+ @Test
+ public final void test() throws InterruptedException {
+ final ThreadRobustList<String> container = new ThreadRobustList<>();
+ final Receiver<Boolean> lock = new Receiver<>();
+ final Reader r = new Reader(container, lock);
+ final Writer w = new Writer(container, lock);
+ final Thread wt = new Thread(w);
+ wt.start();
+ r.run();
+ wt.join();
+ }
+
+}