yonatan
yonatan

Reputation: 187

How to be notified when thread goes down?

In java, I have ExecutorService that runs with while true, and Throwable catch clouse. I find out that from time to time the thread goes down. That means the system stop function. So my question is, first of all, how can I catch the "thread killed" event (in order to send me email on such case)? Also, how can this thread goes down?

the code is:

ExecutorService changesTrackerThread = Executors.newSingleThreadExecutor();
changesTrackerThread.submit(queueUpdater());        

private Runnable queueUpdater() {
    return new Runnable() {
        @Override
        public void run() {
            while (true)
            {
                try
                {                                       
                    // do some code, then sleep
                    Thread.sleep(2000L);
                } catch (Throwable t)
                {
                    _log.error("something bad happened, but the loop should keep running", t);
                }
            }

        }
    };

Upvotes: 3

Views: 164

Answers (2)

Stuart Marks
Stuart Marks

Reputation: 132410

As others have noted, you could replace your while (true) and sleep() loop with a ScheduledExecutorService. Scheduling a repeating task on such a service will return a ScheduledFuture which you can use to check the status of this task or to cancel it if you have a need for that. This will enable you to remove the try/catch block from the code.

Start the service like this:

ScheduledExecutorService svc = Executors.newScheduledThreadPool(1);

I would use newScheduledThreadPool() instead of newSingleThreadScheduledExecutor() since the former will restart threads if necessary.

Then, schedule the work like this:

void doSomeCode() {
    // do some code
}

ScheduledFuture<?> sf = svc.scheduleAtFixedRate(this::doSomeCode, 0L, 2L, TimeUnit.SECONDS);

(Or if you wish you can inline doSomeCode() as a lambda or an anonymous inner class.)

Now what happens if the task fails with an exception? The ScheduledFuture object returned allows you to check status in a variety of ways. If you have a thread that you can dedicate to waiting for failures, you can have it call sf.get() which will throw an ExecutionException that wraps the exception that caused the task to fail. Otherwise, it blocks indefinitely. ScheduledFuture.get() is a bit weird in that unlike an ordinary Future.get() call, it never returns a value; it always throws an exception.

When/if the task fails, the caller of sf.get() can log the exception and resubmit the task, or whatever. If you don't want to block a thread indefinitely, you can poll for failure using sf.isDone() or sf.get(0L, TimeUnit.SECONDS). Note that both overloads of sf.get() communicate all of their return information via the type of a thrown exception, which may make them somewhat inconvenient to use.

You could put exception handling within the task itself, catching Throwable and continuing no matter what, and this will probably work. It does bake the logging/restart/resubmission policy into the task itself, which may be unpleasant. Using ScheduledFuture lets you separate these policies from the actual work performed by the task.

Upvotes: 1

David Limkys
David Limkys

Reputation: 5133

Well first of all, why are you using a while loop here!?

You should use a scheduled executor:

ExecutorService changesTrackerThread = Executors.newSingleThreadScheduledExecutor()();
changesTrackerThread.scheduleAtFixedRate(new queueUpdater(), 0, 2, TimeUnit.SECONDS);        

private Runnable queueUpdater() {
    return new Runnable() {
        @Override
        public void run() {
                try
                {                                       
                    // do some code

                } catch (Throwable t)
                {
                    _log.error("something bad happened", t);
                }

        }
    };

I do not know why your thread dies, show us the full code.

But this way even if the thread dies the Excecutor will rerun it after the given period(2 seconds in this example.

Upvotes: 3

Related Questions