Source:
public void spec103_mustSignalOnMethodsSequentially_shouldFailBy_concurrentlyAccessingOnNext() throws Throwable { final AtomicInteger startedSignallingThreads = new AtomicInteger(0); final int maxSignallingThreads = 10; final ExecutorService signallersPool = Executors.newFixedThreadPool(10); final AtomicBoolean concurrentAccessCaused = new AtomicBoolean(false); final Publisher<Integer> concurrentAccessPublisher = new Publisher<Integer>() { @Override public void subscribe(final Subscriber<? super Integer> s) { s.onSubscribe(new Subscription() { @Override public void request(final long n) { Runnable signalling = new Runnable() { @Override public void run() { for (long i = 0; i < n; i++) { try { if (Thread.interrupted()) { return; } s.onNext((int) i); } catch (Exception ex) { signallersPool.shutdownNow(); if (ex.getMessage().contains("Expected latch to be open")) { if (concurrentAccessCaused.compareAndSet(false, true)) { throw new RuntimeException("Concurrent access detected", ex); } else { return; } } else { throw new RuntimeException(ex); } } } } }; while (startedSignallingThreads.getAndAdd(1) < maxSignallingThreads && !signallersPool.isShutdown()) { try { signallersPool.submit(signalling); } catch (RejectedExecutionException ex) { return; } } } @Override public void cancel() { } }); } }; requireTestFailure(new ThrowingRunnable() { @Override public void run() throws Throwable { customPublisherVerification(concurrentAccessPublisher).spec103_mustSignalOnMethodsSequentially(); } }, "Expected latch to be open during onNext call"); }

Target:
public void spec103_mustSignalOnMethodsSequentially_shouldFailBy_concurrentlyAccessingOnNext() throws Throwable { final AtomicInteger startedSignallingThreads = new AtomicInteger(0); final int maxSignallingThreads = 10; final ExecutorService signallersPool = Executors.newFixedThreadPool(maxSignallingThreads); final AtomicBoolean concurrentAccessCaused = new AtomicBoolean(false); final Publisher<Integer> concurrentAccessPublisher = new Publisher<Integer>() { @Override public void subscribe(final Subscriber<? super Integer> s) { s.onSubscribe(new NoopSubscription() { @Override public void request(final long n) { Runnable signalling = new Runnable() { @Override public void run() { for (long i = 0; i < n; i++) { try { if (Thread.interrupted()) { return; } s.onNext((int) i); } catch (Exception ex) { signallersPool.shutdownNow(); if (ex instanceof TestEnvironment.Latch.ExpectedOpenLatchException) { if (!concurrentAccessCaused.getAndSet(true)) { throw new RuntimeException("Concurrent access detected", ex); } else { return; } } else { throw new RuntimeException(ex); } } } } }; while (startedSignallingThreads.getAndAdd(1) < maxSignallingThreads && !signallersPool.isShutdown()) { try { signallersPool.execute(signalling); } catch (RejectedExecutionException ex) { return; } } } }); } }; try { requireTestFailure(new ThrowingRunnable() { @Override public void run() throws Throwable { customPublisherVerification(concurrentAccessPublisher).spec103_mustSignalOnMethodsSequentially(); } }, "Illegal concurrent access detected"); } finally { signallersPool.shutdownNow(); signallersPool.awaitTermination(1, TimeUnit.SECONDS); } }