CallableWork task = new CallableWork( new AddWork( 1 ) ); FutureTask<Void> futureTask = new FutureTask<>( task ); tasks.add( futureTask );
@Test void mustCombineWorkAsync() throws Exception { makeWorkStuckAtSemaphore( 1 ); AsyncApply a = sync.applyAsync( new AddWork( 1 ) ); AsyncApply b = sync.applyAsync( new AddWork( 1 ) ); AsyncApply c = sync.applyAsync( new AddWork( 1 ) ); semaphore.release( 2 ); a.await(); b.await(); c.await(); assertThat( sum.sum(), is( 4L ) ); assertThat( count.sum(), is( 2L ) ); }
@Test void mustApplyWorkAsyncEvenWhenInterrupted() throws Exception { Thread.currentThread().interrupt(); sync.applyAsync( new AddWork( 10 ) ).await(); assertThat( sum.sum(), is( 10L ) ); assertTrue( Thread.interrupted() ); }
@Test void mustApplyWorkAsync() throws Exception { AsyncApply a = sync.applyAsync( new AddWork( 10 ) ); a.await(); assertThat( sum.sum(), is( 10L ) ); AsyncApply b = sync.applyAsync( new AddWork( 20 ) ); AsyncApply c = sync.applyAsync( new AddWork( 30 ) ); b.await(); c.await(); assertThat( sum.sum(), is( 60L ) ); }
private Future<Void> makeWorkStuckAtSemaphore( int delta ) { semaphore.drainPermits(); Future<Void> concurrentWork = executor.submit( new CallableWork( new AddWork( delta ) ) ); assertThrows( TimeoutException.class, () -> concurrentWork.get( 10, TimeUnit.MILLISECONDS ) ); while ( !semaphore.hasQueuedThreads() ) { usleep( 1 ); } // good, the concurrent AddWork is now stuck on the semaphore return concurrentWork; }
@Override public void apply( Adder adder ) { super.apply( adder ); startLatch.release(); blockLatch.await(); } } ) );
@Override public void apply( Adder adder ) { super.apply( adder ); throw boo; } } );
@Test void mustApplyWorkEvenWhenInterrupted() throws Exception { Thread.currentThread().interrupt(); sync.apply( new AddWork( 10 ) ); assertThat( sum.sum(), is( 10L ) ); assertTrue( Thread.interrupted() ); }
@Override public void apply( Adder adder ) { super.apply( adder ); throw boo; } } );