### Question:
AkkaEngineProvider implements ReactiveStreamsEngine { public static AkkaEngine provider() { AkkaEngine engine = null; if (cachedEngine == null) { synchronized (mutex) { if (cachedEngine == null) { engine = createEngine(); cachedEngine = new WeakReference<>(engine); } } } if (engine == null) { engine = cachedEngine.get(); if (engine == null) { synchronized (mutex) { engine = cachedEngine.get(); if (engine == null) { engine = createEngine(); cachedEngine = new WeakReference<>(engine); } } } } return engine; } AkkaEngineProvider(); static AkkaEngine provider(); @Override Flow.Publisher<T> buildPublisher(Graph graph); @Override SubscriberWithResult<T, R> buildSubscriber(Graph graph); @Override Flow.Processor<T, R> buildProcessor(Graph graph); @Override CompletionStage<T> buildCompletion(Graph graph);  }### Answer:
@Test public void actorSystemIsCleanedUpWhenThereAreNoMoreReferences() throws Exception { AkkaEngine engine = AkkaEngineProvider.provider(); ActorSystem system = ((ActorMaterializer) engine.materializer).system(); engine = null; Thread.sleep(300); System.gc(); FutureConverters.toJava(system.whenTerminated()).toCompletableFuture().get(10, TimeUnit.SECONDS); }
@Test public void aRunningStreamShouldPreventActorSystemFromShuttingDown() throws Exception { AkkaEngine engine = AkkaEngineProvider.provider(); ActorSystem system = ((ActorMaterializer) engine.materializer).system(); Flow.Publisher<Done> publisher = Source.tick( Duration.create(100, TimeUnit.MILLISECONDS), Duration.create(100, TimeUnit.MILLISECONDS), Done.getInstance() ) .runWith(JavaFlowSupport.Sink.asPublisher(AsPublisher.WITHOUT_FANOUT), engine.materializer); AtomicReference<RuntimeException> error = new AtomicReference<>(); ReactiveStreams.fromPublisher(publisher).forEach(d -> { if (error.get() != null) { throw error.get(); } }).build(engine); publisher = null; engine = null; Thread.sleep(300); System.gc(); Thread.sleep(1000); assertFalse(system.whenTerminated().isCompleted()); error.set(new RuntimeException()); Thread.sleep(1000); System.gc(); FutureConverters.toJava(system.whenTerminated()).toCompletableFuture().get(10, TimeUnit.SECONDS); }