### Question:
CentralJobScheduler extends LifecycleAdapter implements JobScheduler, AutoCloseable { @Override public JobHandle scheduleRecurring( Group group, final Runnable runnable, long period, TimeUnit timeUnit ) { return scheduleRecurring( group, runnable, 0, period, timeUnit ); } protected  CentralJobScheduler(); @Override void setTopLevelGroupName( String name ); @Override void init(); @Override Executor executor( Group group ); @Override ExecutorService workStealingExecutor( Group group, int parallelism ); @Override ExecutorService workStealingExecutorAsyncMode( Group group, int parallelism ); @Override ThreadFactory threadFactory( Group group ); @Override JobHandle schedule( Group group, Runnable job ); @Override JobHandle scheduleRecurring( Group group, final Runnable runnable, long period, TimeUnit timeUnit ); @Override JobHandle scheduleRecurring( Group group, Runnable runnable, long initialDelay, long period, TimeUnit unit ); @Override JobHandle schedule( Group group, final Runnable runnable, long initialDelay, TimeUnit unit ); @Override void shutdown(); @Override void close();  }### Answer:
@Test public void shouldCancelRecurringJob() throws Exception { long period = 2; life.start(); JobHandle jobHandle = scheduler.scheduleRecurring( Group.INDEX_POPULATION, countInvocationsJob, period, MILLISECONDS ); awaitFirstInvocation(); jobHandle.cancel( false ); try { jobHandle.waitTermination(); fail( "Task should be terminated" ); } catch ( CancellationException ignored ) { } int recorded = invocations.get(); sleep( period * 100 ); assertThat( invocations.get(), both( greaterThanOrEqualTo( recorded ) ).and( lessThanOrEqualTo( recorded + 1 ) ) ); }