I came across a way of stopping a Java ScheduledExecutorService which runs a periodic background task, after a time limit from this forum discussion.
In my case, I need to stop the ScheduledExecutorService when a certain condition is true. For example, I want to stop printing out "beep {count}", once the count exceeds 5. I have used the previously highlighted example for this purpose.
public class BeeperControl {
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
private int count;
public void beep() {
final Runnable beeper = new Runnable() {
public void run() {
count = count + 1;
System.out.println("beep " + count);
if (count == 5) {
scheduler.shutdown();
}
}
};
final ScheduledFuture<?> beeperHandle = scheduler.scheduleAtFixedRate(
beeper, 1, 1, SECONDS);
}
public static void main(String[] args) {
BeeperControl bc = new BeeperControl();
bc.beep();
}
}
Here, I have checked if the count is equal to 5 and then has used scheduler.shutdown() method to shutdown the ScheduledExecutorService.
My question is whether this is a good practice for the given scenario (as the ScheduledExecutorService is shutdown by a running task) or is there a better alternative which can be used in such a scenario?
Using Mutable state (count variable) in a Multithreaded Environment is not recommended as it may result in stale value in count variable as a Read-Increment-Write (count = count + 1) is taking place.
It is good if you use a AtomicInteger instead of a plain old int for count variable.
public class BeeperControl {
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
private final AtomicInteger count = new AtomicInteger(0);
public void beep() {
final Runnable beeper = new Runnable() {
public void run() {
count.getAndIncrement();
System.out.println("beep " + count);
if (count.get() == 5) {
scheduler.shutdown();
}
}
};
final ScheduledFuture<?> beeperHandle = scheduler.scheduleAtFixedRate(
beeper, 1, 1, SECONDS);
}
public static void main(String[] args) {
BeeperControl bc = new BeeperControl();
bc.beep();
}
}
Shutting down the ScheduledExecutorService by a running task is fine as in many scenarios that is what happens.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With