I need to schedule a task, which runs periodically. The task should check if some conditions are still valid (isValid) and if not, it has to stop the running task and not create any further tasks. I cannot shut down the executor though, as I am using that instance to create new tasks in different thread.
What I have come up with is:
ScheduledFuture<?> scheduledTask = _executor.scheduleWithFixedDelay( () ->
{
try
{
if( isValid() )
{
// Do tasks to close
// Cancel the task, but how?
}
}
catch ( Throwable e)
{
log.fatal( "Unexpected error..", e );
}
}, 0L, 30, TimeUnit.SECONDS );
How do I cancel the currently running task ( scheduledTask )?
Use separate executor service instances. When conditions are such that you no longer need the executor service running your scheduled task, shutdown that service.
You can have the scheduled task shutdown its own executor service.
shutdown
. That local variable go
is an AtomicBoolean
rather than a boolean
/ Boolean
because any variable accessed from within the nested task definition must be either explicitly final
or effectively final
.shutdown
method.You said:
I cannot shut down the executor though, as I am using that instance to create new tasks in different thread.
You can have multiple executor services at the same time. If sharing an executor service is inconvenient, create multiple.
In this example, we start two different tasks in two different scheduled executor services. Both tasks print the current time to the console.
We flip a flag in AtomicBoolean go
to signal when we want the second scheduled executor service's task to halt further scheduling. The task calls shutdown
on its own scheduler.
Instant start = Instant.now();
System.out.println( "START demo. " + start );
ScheduledExecutorService sesX = Executors.newScheduledThreadPool( 3 );
sesX.scheduleAtFixedRate( () -> System.out.println( "X is running. " + Instant.now() + " Elapsed: " + Duration.between( start , Instant.now() ) ) , 0 , 5 , TimeUnit.SECONDS );
ScheduledExecutorService sesY = Executors.newSingleThreadScheduledExecutor();
final AtomicBoolean go = new AtomicBoolean( true );
sesY.scheduleAtFixedRate(
() -> {
if ( go.get() )
{
System.out.println( "Y is running. " + Instant.now() + " Elapsed: " + Duration.between( start , Instant.now() ) );
} else // Else the flag tripped signaling us to stop our work, and to shut down our scheduled executor service.
{
sesY.shutdown();
System.out.println( "Y is STOPPING per boolean flag. " + Instant.now() + " Elapsed: " + Duration.between( start , Instant.now() ) );
}
} ,
0 ,
11 ,
TimeUnit.SECONDS
);
try { Thread.sleep( Duration.ofSeconds( 30 ).toMillis() ); } catch ( InterruptedException e ) { e.printStackTrace(); }
go.set( false ); // Trip the flag for the "X" task to stop its scheduled executor service.
try { Thread.sleep( Duration.ofMinutes( 1 ).toMillis() ); } catch ( InterruptedException e ) { e.printStackTrace(); }
System.out.println( "STOPPING demo. " + Instant.now() + " Elapsed: " + Duration.between( start , Instant.now() ) );
sesX.shutdown();
sesY.shutdown();
System.out.println( "END of demo. " + Instant.now() + " Elapsed: " + Duration.between( start , Instant.now() ) );
To that code you may want to add calls to awaitTermination
to throw an exception if a time-out occurs.
When run, you will see something like this output. Notice how after Y is STOPPING
we see no more occurrences of Y is running.
.
START demo. 2021-10-06T03:22:05.894497Z
Y is running. 2021-10-06T03:22:05.901926Z Elapsed: PT0.007436S
X is running. 2021-10-06T03:22:05.900470Z Elapsed: PT0.005976S
X is running. 2021-10-06T03:22:10.905005Z Elapsed: PT5.010514S
X is running. 2021-10-06T03:22:15.900850Z Elapsed: PT10.006362S
Y is running. 2021-10-06T03:22:16.907107Z Elapsed: PT11.012623S
X is running. 2021-10-06T03:22:20.900625Z Elapsed: PT15.006141S
X is running. 2021-10-06T03:22:25.904249Z Elapsed: PT20.009759S
Y is running. 2021-10-06T03:22:27.906847Z Elapsed: PT22.012356S
X is running. 2021-10-06T03:22:30.901478Z Elapsed: PT25.00699S
X is running. 2021-10-06T03:22:35.906167Z Elapsed: PT30.0117S
Y is STOPPING per boolean flag. 2021-10-06T03:22:38.902688Z Elapsed: PT33.008203S
X is running. 2021-10-06T03:22:40.900736Z Elapsed: PT35.006248S
X is running. 2021-10-06T03:22:45.901721Z Elapsed: PT40.007239S
X is running. 2021-10-06T03:22:50.905250Z Elapsed: PT45.010765S
X is running. 2021-10-06T03:22:55.904860Z Elapsed: PT50.01037S
X is running. 2021-10-06T03:23:00.903331Z Elapsed: PT55.008842S
X is running. 2021-10-06T03:23:05.904016Z Elapsed: PT1M0.009534S
X is running. 2021-10-06T03:23:10.901787Z Elapsed: PT1M5.007306S
X is running. 2021-10-06T03:23:15.903274Z Elapsed: PT1M10.00879S
X is running. 2021-10-06T03:23:20.905279Z Elapsed: PT1M15.010808S
X is running. 2021-10-06T03:23:25.903848Z Elapsed: PT1M20.009362S
X is running. 2021-10-06T03:23:30.901875Z Elapsed: PT1M25.007388S
X is running. 2021-10-06T03:23:35.905661Z Elapsed: PT1M30.011178S
STOPPING demo. 2021-10-06T03:23:35.909920Z Elapsed: PT1M30.015447S
END of demo. 2021-10-06T03:23:35.911568Z Elapsed: PT1M30.017074S
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.