How do I get notified when a thread goes down?

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

code:

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);
                }
            }

        }
    };

      

+3


source to share


2 answers


Okay, in the first place, why are you using a while loop here?

You must use the 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 don't know why your thread is dying, show us the complete code.

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

+3


source


As mentioned by others, you can replace the loop while (true)

and sleep()

on ScheduledExecutorService

. Scheduling a recurring task on such a service returns ScheduledFuture

, which you can use to check the status of that task or cancel it if you need to. This will allow you to remove the try / catch block from your code.

Start the service as follows:

ScheduledExecutorService svc = Executors.newScheduledThreadPool(1);

      

I would use newScheduledThreadPool()

instead newSingleThreadScheduledExecutor()

, as the former would restart threads as needed.

Then plan your work as follows:



void doSomeCode() {
    // do some code
}

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

      

(Or, if you like, you can inline doSomeCode()

as a lambda or anonymous inner class.)

Now what happens if the task finishes with an exception? The returned object ScheduledFuture

allows you to check the status in a variety of ways. If you have a thread that you can devote to waiting for failures, you can invoke a call sf.get()

that will throw ExecutionException

, which will wrap an exception that will cause the task to fail. Otherwise, it blocks indefinitely. ScheduledFuture.get()

It's a little strange that, unlike a regular call, Future.get()

it never returns a value; it always throws an exception.

If / if the task fails, the caller sf.get()

can log an exception and resubmit the task or whatever. If you don't want to block the thread indefinitely, you can poll for failure using sf.isDone()

or sf.get(0L, TimeUnit.SECONDS)

. Note that both overloads sf.get()

bind everything to their return information via the thrown exception type, which can make them somewhat awkward to use.

You can put exception handling on a task by catching Throwable

and continuing with whatever, and it will probably work. It incinerates the registration / restart / re-submission policy in the task itself, which can be frustrating. Use ScheduledFuture

allows you to decouple these policies from the actual work being done by the task.

+1


source







All Articles