-1

I have a code like this:

public class SomeClass
{
    private ScheduledExecutorService executor;
    private ScheduledFuture<?> future;
    private Set<String> keys;
    private ConcurrentMap<String, Something> map;

    public void startTask()
    {
        future = executor.scheduleWithFixedDelay(new SomeTask(), ...);
    }

    public void stopTask()
    {
        future.cancel(true);
        map.clear();
    }

    private class SomeTask implements Runnable
    {
        @Override
        public void run()
        {
            for (String key : keys)
            {
                if (Thread.interrupted())
                {
                    break;
                }

                // Getting value...

                map.put(key, value);
            }
        }
    }
}

I want to make sure that map is empty when stopTask exits.
I am thinking about making the method wait until the task has exited by using some synchronizer, however, I'm not sure which one would work better. There's also may be another, better way to do what I need.

The task has only one instance and can be rescheduled later after cancellation, if it matters.

izstas
  • 5,004
  • 3
  • 42
  • 56

1 Answers1

0

I've basically two answers to your question:

Whenever you call future.cancel(true) or executor.shutdownNow()it calls interrupt() either for the one task or for all threads in the thread pool. The interrupt() is ignored by any Java method except the ones that can throw InterruptedException, like e.g. Thread.sleep(). In your case, the code to "get value" and put that value into the map will not be interrupted. The only possible point of interruption is where you've code it - or, if any method you call to get the value might throw InterruptedException.

But, do you really just want to stop the one task, not the scheduler itself? I would prefer to stop scheduling instead of just canceling on task. Here's a code snippet I use to stop any kind of thread pool and wait till all tasks have finished:

public void stopTask()
{
    executor.shutdownNow(); // Stops submitting new tasks and sends interrupt to running tasks

    // Wait for tasks to complete
    while(!executor.isTerminated()) try {
        executor.awaitTermination(1L, TimeUnit.MINUTES);
        if(!executor.isTerminated())
            System.out.println("Still waiting for scheduled tasks to finish");
    } catch(InterruptedException e) {}

    map.clear();
    System.out.println(map);
}

The shutdownNow() ensures, that the current running task gets interrupt()called.

jboi
  • 11,324
  • 4
  • 36
  • 43