public class DeadlockDetectingListeningExecutorServiceTest {
interface InitialInvoker {
- void invokeExecutor( ListeningExecutorService executor, Runnable task );
+ void invokeExecutor(ListeningExecutorService executor, Runnable task);
}
static final InitialInvoker SUBMIT = ListeningExecutorService::submit;
static final InitialInvoker EXECUTE = Executor::execute;
- @SuppressWarnings("serial")
public static class TestDeadlockException extends Exception {
+ private static final long serialVersionUID = 1L;
+
}
private static final Supplier<Exception> DEADLOCK_EXECUTOR_SUPPLIER = TestDeadlockException::new;
@After
public void tearDown() {
- if (executor != null ) {
+ if (executor != null) {
executor.shutdownNow();
}
}
DeadlockDetectingListeningExecutorService newExecutor() {
- return new DeadlockDetectingListeningExecutorService( Executors.newSingleThreadExecutor(),
- DEADLOCK_EXECUTOR_SUPPLIER );
+ return new DeadlockDetectingListeningExecutorService(Executors.newSingleThreadExecutor(),
+ DEADLOCK_EXECUTOR_SUPPLIER);
}
@Test
ListenableFuture<String> future = executor.submit(() -> "foo");
- assertEquals( "Future result", "foo", future.get( 5, TimeUnit.SECONDS ) );
+ assertEquals( "Future result", "foo", future.get( 5, TimeUnit.SECONDS));
// Test submit with Runnable.
// Test submit with Runnable and value.
- future = executor.submit(() -> {
- }, "foo" );
+ future = executor.submit(() -> { }, "foo");
- assertEquals( "Future result", "foo", future.get( 5, TimeUnit.SECONDS ) );
+ assertEquals("Future result", "foo", future.get(5, TimeUnit.SECONDS));
}
@Test
executor = newExecutor();
- testNonBlockingSubmitOnExecutorThread( SUBMIT, SUBMIT_CALLABLE );
- testNonBlockingSubmitOnExecutorThread( SUBMIT, SUBMIT_RUNNABLE );
- testNonBlockingSubmitOnExecutorThread( SUBMIT, SUBMIT_RUNNABLE_WITH_RESULT );
+ testNonBlockingSubmitOnExecutorThread(SUBMIT, SUBMIT_CALLABLE);
+ testNonBlockingSubmitOnExecutorThread(SUBMIT, SUBMIT_RUNNABLE);
+ testNonBlockingSubmitOnExecutorThread(SUBMIT, SUBMIT_RUNNABLE_WITH_RESULT);
- testNonBlockingSubmitOnExecutorThread( EXECUTE, SUBMIT_CALLABLE );
+ testNonBlockingSubmitOnExecutorThread(EXECUTE, SUBMIT_CALLABLE);
}
- void testNonBlockingSubmitOnExecutorThread( final InitialInvoker initialInvoker,
- final Invoker invoker ) throws Throwable {
+ void testNonBlockingSubmitOnExecutorThread(final InitialInvoker initialInvoker, final Invoker invoker)
+ throws Throwable {
final AtomicReference<Throwable> caughtEx = new AtomicReference<>();
- final CountDownLatch futureCompletedLatch = new CountDownLatch( 1 );
+ final CountDownLatch futureCompletedLatch = new CountDownLatch(1);
- Runnable task = () -> Futures.addCallback( invoker.invokeExecutor( executor, null ), new FutureCallback() {
+ Runnable task = () -> Futures.addCallback(invoker.invokeExecutor(executor, null), new FutureCallback<Object>() {
@Override
- public void onSuccess( final Object result ) {
+ public void onSuccess(final Object result) {
futureCompletedLatch.countDown();
}
@Override
- public void onFailure( final Throwable t ) {
- caughtEx.set( t );
+ public void onFailure(final Throwable t) {
+ caughtEx.set(t);
futureCompletedLatch.countDown();
}
- } );
+ });
- initialInvoker.invokeExecutor( executor, task );
+ initialInvoker.invokeExecutor(executor, task);
- assertTrue( "Task did not complete - executor likely deadlocked",
- futureCompletedLatch.await( 5, TimeUnit.SECONDS ) );
+ assertTrue("Task did not complete - executor likely deadlocked",
+ futureCompletedLatch.await(5, TimeUnit.SECONDS));
- if (caughtEx.get() != null ) {
+ if (caughtEx.get() != null) {
throw caughtEx.get();
}
}
executor = newExecutor();
- testBlockingSubmitOnExecutorThread( SUBMIT, SUBMIT_CALLABLE );
- testBlockingSubmitOnExecutorThread( SUBMIT, SUBMIT_RUNNABLE );
- testBlockingSubmitOnExecutorThread( SUBMIT, SUBMIT_RUNNABLE_WITH_RESULT );
+ testBlockingSubmitOnExecutorThread(SUBMIT, SUBMIT_CALLABLE);
+ testBlockingSubmitOnExecutorThread(SUBMIT, SUBMIT_RUNNABLE);
+ testBlockingSubmitOnExecutorThread(SUBMIT, SUBMIT_RUNNABLE_WITH_RESULT);
- testBlockingSubmitOnExecutorThread( EXECUTE, SUBMIT_CALLABLE );
+ testBlockingSubmitOnExecutorThread(EXECUTE, SUBMIT_CALLABLE);
}
- void testBlockingSubmitOnExecutorThread( final InitialInvoker initialInvoker,
- final Invoker invoker ) throws Exception {
+ void testBlockingSubmitOnExecutorThread(final InitialInvoker initialInvoker, final Invoker invoker)
+ throws Exception {
final AtomicReference<Throwable> caughtEx = new AtomicReference<>();
- final CountDownLatch latch = new CountDownLatch( 1 );
+ final CountDownLatch latch = new CountDownLatch(1);
Runnable task = () -> {
try {
- invoker.invokeExecutor( executor, null ).get();
- } catch( ExecutionException e ) {
- caughtEx.set( e.getCause() );
- } catch( Throwable e ) {
- caughtEx.set( e );
+ invoker.invokeExecutor(executor, null).get();
+ } catch(ExecutionException e) {
+ caughtEx.set(e.getCause());
+ } catch(Throwable e) {
+ caughtEx.set(e);
} finally {
latch.countDown();
}
};
- initialInvoker.invokeExecutor( executor, task );
-
- assertTrue( "Task did not complete - executor likely deadlocked",
- latch.await( 5, TimeUnit.SECONDS ) );
+ initialInvoker.invokeExecutor(executor, task);
- assertNotNull( "Expected exception thrown", caughtEx.get() );
- assertEquals( "Caught exception type", TestDeadlockException.class, caughtEx.get().getClass() );
+ assertTrue("Task did not complete - executor likely deadlocked", latch.await( 5, TimeUnit.SECONDS));
+ assertNotNull("Expected exception thrown", caughtEx.get());
+ assertEquals("Caught exception type", TestDeadlockException.class, caughtEx.get().getClass());
}
@Test
public void testListenableFutureCallbackWithExecutor() throws InterruptedException {
String listenerThreadPrefix = "ListenerThread";
- ExecutorService listenerExecutor = Executors.newFixedThreadPool( 1,
- new ThreadFactoryBuilder().setNameFormat( listenerThreadPrefix + "-%d" ).build() );
+ ExecutorService listenerExecutor = Executors.newFixedThreadPool(1,
+ new ThreadFactoryBuilder().setNameFormat(listenerThreadPrefix + "-%d").build());
executor = new DeadlockDetectingListeningExecutorService(
- Executors.newSingleThreadExecutor(
- new ThreadFactoryBuilder().setNameFormat( "SingleThread" ).build() ),
- DEADLOCK_EXECUTOR_SUPPLIER, listenerExecutor );
+ Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat("SingleThread").build()),
+ DEADLOCK_EXECUTOR_SUPPLIER, listenerExecutor);
try {
- testListenerCallback( executor, SUBMIT_CALLABLE, listenerThreadPrefix );
- testListenerCallback( executor, SUBMIT_RUNNABLE, listenerThreadPrefix );
- testListenerCallback( executor, SUBMIT_RUNNABLE_WITH_RESULT, listenerThreadPrefix );
+ testListenerCallback(executor, SUBMIT_CALLABLE, listenerThreadPrefix);
+ testListenerCallback(executor, SUBMIT_RUNNABLE, listenerThreadPrefix);
+ testListenerCallback(executor, SUBMIT_RUNNABLE_WITH_RESULT, listenerThreadPrefix);
} finally {
listenerExecutor.shutdownNow();
}