diff options
Diffstat (limited to 'yolean/src/test/java/com/yahoo/yolean/concurrent/MemoizedTest.java')
-rw-r--r-- | yolean/src/test/java/com/yahoo/yolean/concurrent/MemoizedTest.java | 101 |
1 files changed, 0 insertions, 101 deletions
diff --git a/yolean/src/test/java/com/yahoo/yolean/concurrent/MemoizedTest.java b/yolean/src/test/java/com/yahoo/yolean/concurrent/MemoizedTest.java deleted file mode 100644 index 7f2f49c75f2..00000000000 --- a/yolean/src/test/java/com/yahoo/yolean/concurrent/MemoizedTest.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.yahoo.yolean.concurrent; - -import org.junit.Test; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.Phaser; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Supplier; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertThrows; -import static org.junit.Assert.fail; - -/** - * @author jonmv - */ -public class MemoizedTest { - - final Phaser phaser = new Phaser(); - final int threads = 128; - - @Test - public void test() throws ExecutionException, InterruptedException { - var lazy = new Memoized<>(new OnceSupplier(), OnceCloseable::close); - phaser.register(); // test thread - phaser.register(); // whoever calls the factory - - Phaser latch = new Phaser(threads + 1); - ExecutorService executor = Executors.newFixedThreadPool(threads); - List<Future<?>> futures = new ArrayList<>(); - for (int i = 0; i < 128; i++) { - futures.add(executor.submit(() -> { - latch.arriveAndAwaitAdvance(); - lazy.get().rendezvous(); - while (true) lazy.get(); - })); - } - - // All threads waiting for latch, will race to factory - latch.arriveAndAwaitAdvance(); - - // One thread waiting in factory, the others are blocked, will go to rendezvous - phaser.arriveAndAwaitAdvance(); - - // All threads waiting in rendezvous, will repeatedly get until failure - phaser.arriveAndAwaitAdvance(); - - // Unsynchronized close should be detected by all threads - lazy.close(); - - // Close should carry through only once - lazy.close(); - - assertEquals("already closed", - assertThrows(IllegalStateException.class, lazy::get).getMessage()); - - for (Future<?> future : futures) - assertEquals("java.lang.IllegalStateException: already closed", - assertThrows(ExecutionException.class, future::get).getMessage()); - - executor.shutdown(); - } - - @Test - public void closeBeforeFirstGet() throws Exception { - OnceSupplier supplier = new OnceSupplier(); - Memoized<OnceCloseable, ?> lazy = Memoized.of(supplier); - lazy.close(); - assertEquals("already closed", - assertThrows(IllegalStateException.class, lazy::get).getMessage()); - lazy.close(); - assertFalse(supplier.initialized.get()); - } - - class OnceSupplier implements Supplier<OnceCloseable> { - final AtomicBoolean initialized = new AtomicBoolean(); - @Override public OnceCloseable get() { - phaser.arriveAndAwaitAdvance(); - if ( ! initialized.compareAndSet(false, true)) fail("initialized more than once"); - phaser.bulkRegister(threads - 1); // register all the threads who didn't get the factory - return new OnceCloseable(); - } - } - - class OnceCloseable implements AutoCloseable { - final AtomicBoolean closed = new AtomicBoolean(); - @Override public void close() { - if ( ! closed.compareAndSet(false, true)) fail("closed more than once"); - } - void rendezvous() { - phaser.arriveAndAwaitAdvance(); - } - } - -} |