ScheduledExecutorService - safe shutdown and restart if things go bad - java

I wanted a little confirmation if this was the right way to go about implementing my use case.
I am working on a swing app. This app when it starts, should launch a service thread at the background, that keeps polling a database and does some stuff at an interval of 30 minutes.
These are the things that need to happen
Starts off a service that executes at a fixed rate of 30 minutes.
If an exception happens while the service is executing, it should notify the user and restart itself.
When the user quits the application, all backround threads should be stopped.
I have written this code below. I needed some confirmation whether this was the right way to go about building something like this. Specifically I had the below questions
The while(true) loop is used to restart the service when things go bad. Could there be any issues with this? Is there a better way of doing this?
What is the most reliable way to shutdown the entire thing when the user exits. I want the user's exit to be quick and at the same time the background thread should have completed somewhere in between. Is there someway of making the background thread signify that it has reached a checkpoint and that it can be shutdown? Like for example, if I am looping through many records in the database and when shutdown is called, if the thread is working on one record, it completes working on that record and then proceeds to shutdown?
import java.util.concurrent.*;
public class ScheduledFutureTest {
private static int counter=0;
public static void main(String[] args) {
try{
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.submit(new Callable<Void>(){
#Override
public Void call() throws Exception {
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
ScheduledFuture<?> future=schedule(scheduledExecutorService);
while(true){
try{
future.get();
}catch (Exception e){
System.out.println("Exception caught.. now need to restart scheduler");
scheduledExecutorService.shutdownNow();
// restart scheduler
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
future=schedule(scheduledExecutorService);
System.out.println("Restarted the scheduler");
}
}
}
public ScheduledFuture<?> schedule(ScheduledExecutorService scheduledExecutorService){
return scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
System.out.println(counter++);
// simulating an exception to occur
if (counter % 3 == 0) {
throw new RuntimeException("Exception thrown from runnable - counter ="+counter);
}
}
}, 0, 1, TimeUnit.SECONDS); // actually 30 minutes
}
});
// work with other stuff regarding the swing app
System.out.println(" continuing with working on other stuff ");
}catch (Exception e){
e.printStackTrace();
}
}
}

Related

Spontaneous execution of code in periodically running thread

I have a thread which executes code periodically, e. g. every 10 seconds. I'd like to have the option to also invoke the same code in a spontaneous way and not have to wait 10 seconds. But the code of the automatic and spontaneous execution must never run concurrently, instead they should run in sequence if the user presses the execute button while the thread is invoking the same method.
Does anyone know a good pattern or even a class that can address this kind of requirement?
First thing that comes to mind would be to make the work method synchronized. But in that case the manual execution (e. g. button press) is blocked and has to wait until the method in the thread is finished. Is there a better approach without blocking?
Example:
public class Executor extends Thread {
// endless loop, executes work method periodically with pause inbetween
#Override
public void run() {
while( true) {
work( "automatic");
pause(10000);
}
}
// Working method that's executed periodically or manually
private synchronized void work( String text) {
System.out.println( "Working " + text + " " + System.currentTimeMillis());
}
// helper method that pauses the thread
private static void pause( long sleepMs) {
try {
Thread.sleep(sleepMs);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// start automatic execution
Executor executor = new Executor();
executor.start();
// pause a while
pause(1000);
// manual execution
executor.work( "manual");
}
}
Edit: Solution for my requirement:
public class ScheduledExecutor {
public static void main(String[] args) throws InterruptedException {
ScheduledThreadPoolExecutor executor = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(1);
executor.scheduleWithFixedDelay(new Work("auto"), 0, 10, TimeUnit.SECONDS);
Thread.sleep(1000);
executor.execute(new Work("manual"));
}
public static class Work implements Runnable {
String text;
public Work(String text) {
this.text = text;
}
#Override
public void run() {
System.out.println("Working " + text + " " + System.currentTimeMillis());
}
}
}
I would create a new, single-thread executor service:
ExecutorService executorService = Executors.newFixedThreadPool(1);
Then, I would set up a timer that feeds the executorService a task once every 10 seconds.
new Timer(10000, new ActionListener {
public void actionPerformed(ActionEvent evt) {
executorService.execute(() -> doWhatever());
}
}).start();
Finally, you can call executorService.execute(() -> doWhatever()); in your button press handler, or wherever else you want in your code.
Only one activation of doWhatever() will run at a time because the executorService has only one thread on which to run them. And, your button press handler will never have to wait, because it does nothing but put a new object on a queue.
I have a thread which executes code periodically, e. g. every 10 seconds. I'd like to have the option to also invoke the same code in a spontaneous way and not have to wait 10 seconds.
A simple way to do this in your code is not to pause by using Thread.sleep(...) but rather do wait(...). Then whenever you want the command to wakeup and run manually it just does a notify().
So you code would look something like:
while( true) {
work( "automatic");
synchronized (this) {
try {
// wait for a bit but allow someone else to awake us to run manually
wait(10000);
} catch (InterruptedException ie) {
// always a good pattern
Thread.currentThread().interrupt();
return;
}
}
}
Then when you want to have it run manually you do:
synchronized (executor) {
executor.notify();
}
The notify will awaken the thread immediately so that it can run it's task. The work method then does not need to be synchronized because only the Executor thread is running it.
NOTE: As pointed out by #shinobi, using wait() like this could suffer from spurious wake-ups which can happen with certain OS thread implementations.
Lastly, it is a better practice to make Executor implement Runnable as opposed to extending Thread.
Share a semaphore between the server thread (the one that executes the task) and client threads (the ones that need to trigger immediate execution):
Semaphore sem = new Semaphore( 0 );
The server thread needs to execute the following code (note that it's an endless loop — you'll likely want to plug-in your program termination check as the condition to while()):
while( true ) {
try {
sem.tryAcquire( 10, TimeUnit.SECONDS );
} catch( InterruptedException e ) {
continue;
}
runTask();
sem.drainPermits();
}
Then, in order to trigger immediate execution, the client thread needs to do:
sem.release();
Thus, the server thread will execute the task upon either acquiring a permit from the semaphore as soon as a client thread releases one (triggered immediate execution,) or timing-out in Semaphore.tryAcquire() (periodic executions 10s apart, end-to-start.) Having executions 10s apart start-to-start will take some slightly more involved logic, as well as keeping track of last execution's starting time, but the basic idea remains the same.
You need to drain the permits each time in order to avoid multiple back-to-back executions of the task, in cases where it might be triggered for immediate execution while still being executed.

Stop a Runnable in a Thread imediatly

I try to implement a version of software transactional memory library in java with some sort of scheduler which holds some Thread objects. I want to implement a mechanism where the scheduler tells the Thread to immediatly stop execution, drop its Runnable, create a new one and rerun it. This is really half cooked so far but what I don't want is to recreate the hole Thread because it will work as a state holder for several Variables (deepcopies of other variables only the Thread has - copy tasks are a choke here so the Thread should not be fully recreated)
My problem is that I don't know about anything that terminates a method while it executes and frees all the resources (If the scheduler tells the thread to restart everything the Runnable did is invalid and must be redone) and start the run method again with fresh input variables.
The goal is to avoid unecesarry executions and there should be no variable in the runnable which asks if it was interreupted to then skip the execution or something. Just stop the execution and kill it from something the runnable itself is not aware off. I hope it's clear what I want if not please ask for the unclear points help would be very appreciated :)
A simple Tutorial to cancel the Runnable and start it again.
public class RestartThreadTutorial {
public static void main(String args[]){
ExecutorService executorService = Executors.newFixedThreadPool(5);
Future<?> taskHandler = executorService.submit(new Task());
//restart the task after 3 seconds.
try{
Thread.sleep(3000);
}catch(InterruptedException e){
//empty
}
taskHandler.cancel(true); //it will cancel the running thread
if (taskHandler.isCancelled()==true){//check the thread is cancelled
executorService.submit(new Task());//then create new thread..
}
}
public static class Task implements Runnable{
private int secondsCounter;
#Override
public void run(){
while(true){
System.out.println("Thread -"+Thread.currentThread().getName()+"elapsed - "+ (secondsCounter++) +"second");
try{
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
break;
}
}
}
}
}

How to manage worker thread lifecycles when main Java thread terminates?

I want to achieve the following: When my application starts, the main thread will start 1+ worker threads that should run in the background, and periodically do things behind the scenes. These should not block the main thread: once main starts the workers, it continues doing its own thing until:
The main thread finishes (normal application termination) - in the case of a command-line utility this is when the end of the main(String[]) method is reached; in the case of a Swing GUI it could be when the user selects the File >> Exit menu, etc.
The operating system throws a kill command (SIGKILL, etc.)
An unexpected, uncaught exception occurs in the main thread, effectively killing it (this is just an unpolite version of #1 above)
Once started/submitted from the main thread, I want all the worker threads (Runnables) to essentially have their own life cycle, and exist independently of the main thread. But, if the main thread dies at any time, I want to be able to block (if at all possible) the main thread until all the workers are finished shutting down, and then "allow" the main thread to die.
My best attempt so far, although I know I'm missing pieces here and there:
public class MainDriver {
private BaneWorker baneWorker;
private ExecutorService executor = Executors.newCachedThreadPool();
public static void main(String[] args) {
MainDriver driver = new MainDriver();
driver.run();
// We've now reached the end of the main method. All workers should block while they shutdown
// gracefully (if at all possible).
if(executor.awaitTermination(30, TimeUnit.SECONDS))
System.out.println("Shutting down...");
else {
System.out.println("Forcing shut down...");
executor.shutdownNow();
}
}
private void run() {
// Start all worker threads.
baneWorker = new BaneWorker(Thread.currentThread());
// More workers will be used once I get this simple example up and running...
executor.submit(baneWorker);
// Eventually submit the other workers here as well...
// Now start processing. If command-line utility, start doing whatever the utility
// needs to do. If Swing GUI, fire up a parent JFrame and draw the application to the
// screen for the user, etc.
doStuff();
}
private void doStuff() {
// ??? whatever
}
}
public class BaneWorker implements Runnable {
private Timer timer;
private TimerTask baneTask;
private Thread mainThread;
public BaneWorker(Thread mainThread) {
super();
this.mainThread = mainThread;
}
#Override
public void run() {
try {
timer = new Timer();
baneTask = new TimerTask() {
#Override
public void run() {
System.out.println("When the main thread is ashes...");
}
};
// Schedule the baneTask to kick off every minute starting now.
timer.scheduleAtFixedRate(baneTask, new Date(), 60 * 1000);
} catch(InterruptedException interrupt) {
// Should be thrown if main thread dies, terminates, throws an exception, etc.
// Should block main thread from finally terminating until we're done shutting down.
shutdown();
}
}
private void shutdown() {
baneTask.cancel();
System.out.println("...then you have my permission to die.");
try {
mainThread.join();
} catch(InterruptedException interrupt) {
interrupt.printStackTrace;
}
}
}
Am I on-track or way off-base here? What do I need to change to make this work the way I need it to? I'm new to Java concurrency and am trying my best to use the Concurrency API correctly, but stumbling around a bit. Any ideas? Thanks in advance!
The main thread must signal the worker threads to terminate (generally this is achieved just by using a flag) and then it should call join on every thread to wait for their termination. Have a look here: Java: How to use Thread.join
You can use Runtime.addShutdownHook to register an un-started thread that is executed when a JVM is terminated, the system is shutting down etc. This code can do some cleanup itself, or perhaps notify running daemon threads to finish their work. Any such cleanup code must be relatively fast, because on many systems programs have only a limited time to do cleanup before they're forcibly terminated.
Perhaps you could also consider making your background thread daemon threads. Then they will not block the JVM when main finishes and will be still running during the clean-up phase.
Note that you can't intercept SIGKILL - this signal is designed to be unavoidable and immediate. But it should work with SIGTERM, SIGHUP and similar signals.
Update: You can easily create ExecutorServices that run daemon threads. All you need is to create a proper ThreadFactory:
public static class DaemonFactory
implements ThreadFactory
{
#Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setDaemon(true);
return t;
}
}
than you create an ExecutorService like
public static void main(String argv[])
throws Exception
{
ExecutorService es
= Executors.newCachedThreadPool(new DaemonFactory());
// ^^^^^^^^^^^^^^^^^^^
es.submit(new Callable<Object>() {
public Object call() throws Exception {
Thread.sleep(100);
System.err.println("Daemon: " +
Thread.currentThread().isDaemon());
return null;
}
});
// Without this, JVM will terminate before the daemon thread prints the
// message, because JVM doesn't wait for daemon threads when
// terminating:
es.awaitTermination(3, TimeUnit.SECONDS);
}
Concerning Thread.join(), you shouldn't try to use it on threads managed by an ExecutorService. It's the responsibility of the executor to manage them. You have no reliable way how to enumerate its threads, the executor can create and destroy threads depending on its configuration etc. The only reliable way is to call shutdown(); and then awaitTermination(...);.
If SIGKILL is a unix "kill -9" there's nothing you can do about it.
For graceful exits, use a try/catch/finally in your main. The catch will catch your exceptions and allow you to do what needs to be done (recover? abort?) The finally will give you the hook to spin down your threads gracefully.
Reviewing your code quickly, I don't see where you're keeping track of your thread instances. You'll need those if you're going to tell them to spin down.
psuedocode:
static Main(...) {
ArrayList threads = new ArrayList();
try {
for (each thread you want to spin up) {
threads.add(a new Thread())
}
}
catch { assuming all are fatal. }
finally {
for(each thread t in threads) {
t.shutdown();
t.join(); /* Be prepared to catch (and probably ignore) an exception on this, if shutdown() happens too fast! */
}
}

Properly writing task that ExecutorService.shutdownNow() can stop?

I have a processing loop of the form
while (true) {
doWork();
Thread.sleep(SLEEP_INTERVAL);
}
I want to make a Runnable out of this that can play well with ExecutorService and which will exit when ExecutorService.shutdownNow() is called.
I'm looking to write it this way:
public WorkerTask implements Runnable
{
#Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
doWork();
try {
Thread.sleep(SLEEP_INTERVAL);
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
Simple testing shows it at least appearing to work in that the task gets interrupted and will exit and the ExecutorService will shut down, and appears to do so whether the interrupt arrives while doWork() is processing or during the sleep. (By varying how much work doWork() does and how big SLEEP_INTERVAL is I can pretty much control where the interrupt happens).
But when I google I see examples using Thread.interrupted() as well as Thread.currentThread().isInterrupted(). I understand that the former clears the interrupted flag while the latter leaves it, but is there any other difference I need to care about?
I also see versions where the result of Thread.currentThread().isInterrupted() or Thread.interrupted() is stored in a volatile variable and that variable is used as the while loop test condition. Is that just a style or is there a need to do that? In what I've written do I have to worry that somehow something can clear the interrupt flag between when it is set (whether by being received when the thread is live, or by my catching InterruptedException and reasserting the flag) and when Thread.currentThread().isInterrupted() is called in the loop test?
Your code looks fine to me. Introducing an additional volatile variable would be unnecessary complexity: the interrupt status does the job.
The recommended way, in Java Concurrency in Practice, to deal with interrupts in tasks is to either throw an InterruptedException (this is doable if the task is a Callable and not a Runnable), or to make sure the interrupt status is set and to exit from the task ASAP. Your code does that well.
Could you take a look at ScheduledExecutorService if it matches your requirements:
class BeeperControl {
private final ScheduledExecutorService scheduler =
Executors.newScheduledThreadPool(1);
public void beepForAnHour() {
final Runnable beeper = new Runnable() {
public void run() { System.out.println("beep"); }
};
final ScheduledFuture<?> beeperHandle =
scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS);
scheduler.schedule(new Runnable() {
public void run() { beeperHandle.cancel(true); }
}, 60 * 60, SECONDS);
}
}}
Basically you should take advantage of java.util.concurrent libraries here .You should submit your task via ExecutorService.submit()and then call blocking methods like Future.get() , then you can be sure that those methods will respond to interruption as soon as possible by throwing an ExecutionException() .You probably should get rid of that Thread.sleep() since it is doing nothing . You want to sniff an interrupt as quickly as possible .You possibly also want to wait for a timeout in case your task is doing something inifinitely . So if the task terminates with a TimeOutException , the task is cancelled via its Future.
I call cancel() unconditionally since cancelling a completed task has no effect.
In that case you can do some thing like :
public static void main(String[] args) {
WorkerTask runnable;
TimeUnit unit;
Future<?> task = executor.submit(workerTask);
try{
task.get(timeout,unit);
} catch(TimeoutException e){
}catch(ExecutionException e){
throw e.getCause();
} finally{
//Harmless if the task already completed
task.cancel(true);
}
}
}

Java create background thread which does something periodically

Is it possible to create a separate background thread which would separately do some stuff?
I've tried the following program but it doesn't work as I expect.
public class Test {
private static class UpdaterThread extends Thread {
private final int TIMEOUT = 3000;
public void run() {
while (true) {
try {
Thread.sleep(TIMEOUT);
System.out.println("3 seconds passed");
} catch (InterruptedException ex) {
}
}
}
}
/**
* #param args
* the command line arguments
*/
public static void main(String[] args) {
try {
Thread u = new UpdaterThread();
u.start();
while (true) {
System.out.println("--");
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
I expected that every 3 seconds "3 seconds passed" will be printed in the flow of multiple "--" strings.
In fact "3 seconds passed" is never printed. Why? And how can I create a background thread which would do something independantly from the main thread?
Use java.util.TimerTask and java.util.Timer:
Timer t = new Timer();
t.scheduleAtFixedRate(
new TimerTask()
{
public void run()
{
System.out.println("3 seconds passed");
}
},
0, // run first occurrence immediately
3000); // run every three seconds
It does print "3 seconds passed". Remove the System.out.println("--") and you will see them more easily ;-)
Now you could also use a ScheduledExecutorService, and use a Runnable instead of a Thread:
public class Test {
private static class Updater implements Runnable {
#Override
public void run() {
System.out.println("3 seconds passed");
}
}
public static void main(String[] args) throws InterruptedException {
Runnable r = new Updater();
ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
service.scheduleAtFixedRate(r, 0, 3, TimeUnit.SECONDS);
Thread.sleep(10000);
service.shutdown();
}
}
You can use the above approach to run stuff periodically, although a TimerTask may be simpler.
With respect to your output, I suspect your main thread isn't allowing your UpdaterThread to run, since it's in a very tight loop. Note that this would be dependent on CPUs/cores available etc.
Have you considered sleeping in your main thread, or using Thread.yield() ? Note the provisos in that linked page:
When to use yield()?
I would say practically never. Its behaviour isn't standardly defined
and there are generally better ways to perform the tasks that you
might want to perform with yield(): if you're trying to use only a
portion of the CPU, you can do this in a more controllable way by
estimating how much CPU the thread has used in its last chunk of
processing, then sleeping for some amount of time to compensate: see
the sleep() method;
Note also this interesting article on handling thread interruptions.
There are lot of answers but nobody says why his example was not working. System.out is output stream, so after you have started write to this stream JAVA locks it and all other threads will wait while lock is applied to stream. After the stream will have unlocked another thread will be able to work with this stream.
To make your example working you should add Thread.sleep into while loop in the main thread.
I would recommend using a ScheduledExecutorService. To run your UpdaterThread() every 3 seconds, you can do like this:
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(new UpdaterThread(), 0, 3000, TimeUnit.MILLISECONDS);
You can read more here: Java Tutorials - Executor Interfaces.

Categories

Resources