简体   繁体   中英

How to cancel current task using ScheduledExecutorService?

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 multiple executors

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.

  • In code below, my task accesses the scheduled executor service as a local variable in order to call 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 .
  • Alternatively, you could pass the scheduled executor service to the constructor of your task. That task would keep a reference internally, to later call its 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.

Example code

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM