Re: Continuously re-spawning a stopped/killed thread

Volkan Yazıcı via Concurrency-interest <[email protected]> Fri, 18 Dec 2020 13:15:40 +0100
Newsgroups gmane.comp.java.jsr.166-concurrency
Message-ID <CAP7pH7tQVXf_jkn-FBP71jMPfuzZkT2N-Af_MCLk-41yn3zejg@mail.gmail.com>
Indeed I don't want to deal with hostile interruptions of my thread, though
I want to keep it alive.

Maybe some historical context would help to express my problem better. In
the beginning, we had the following form:

try { delegate(); }
catch (Exception ...) { ... }

Though later on we figured
<https://github.com/vy/log4j2-redis-appender/issues/11#issue-721272982> it
is pretty common to get harmless(?) Throwables that are not Exceptions,
e.g., ExceptionInInitializerError. Hence I happened to change the code as
follows:

try { delegate(); }
catch (Throwable ...) { ... }

Then we received the complaint regarding ThreadDeath. Rather than trying to
engineer a smart try-catch block, I want to return back to the first simple
form where I only catch Exceptions, but then I need to get the thread
automatically respawned on unintended deaths. I thought of leveraging the
"unhandled exception handler" mechanism of Executors for this automatic
respawning. What do you think?

On Fri, Dec 18, 2020 at 12:45 PM Thorsten <[email protected]> wrote:

> Hello,
>
> ThreadDeath is part of the Thread#stop  mechanism. This whole concept has
> been deprecated for over 10 Years or so. If you "need"/"want" to implement
> according to the deprecated/broken Thread#stop specification : Yes you need
> to add a special catch Handler for ThreadDeath.
>
> However this doesn't really make the world a much better place. Why would
> a user call Thread.stop? To shutdown your service. But you already have
> implemented a better shutdown mechanism, as has been described in the
> Thread.stop javadoc:
>
>  Many uses of stop should be replaced by code that simply modifies some
> variable to indicate that the target thread should stop running. The target
> thread should check this variable regularly, and return from its run method
> in an orderly fashion if the variable indicates that it is to stop running.
>
> So adding a ThreadDeathHandler only does something if somebody is using
> the API wrong in the first place, and it's not really clear if that
> something is good.
>
> Best Regards,
>
> Thorsten
>
>
> Am 18/12/2020 um 12:05 schrieb Volkan Yazıcı via Concurrency-interest:
>
> *[Today while checking the mailing-list archives to share the link of my
> question with a friend, I noticed Martin Buchholz's response, which I could
> find neither in my inbox, nor in spam folders. Maybe missed during the
> recent Google outage?]*
>
> On Tue Dec 15 15:44:21 EST 2020 Martin Buchholz wrote:
> > Why not just try { ... } catch (...) { handle ... } in your thread's
> main method?
>
> That is what I had in mind initially:
>
> try { delegate(); }
> catch (ThreadDeath ...) { ... }
> catch (Throwable ...) { ... }
>
> But is this it? These sort of blacklists always make me nervous. I did not
> know about ThreadDeath until a user complaint. Maybe there are more such
> corner cases that I need to prevent against, hence my question to this list.
>
>
> On Mon, Dec 14, 2020 at 11:24 AM Volkan Yazıcı <[email protected]>
> wrote:
>
>> Hello,
>>
>> In Log4j, we need to run a background task and keep it alive — unless JVM
>> is stopped or our *while (!stopped)* condition fails after an interrupt.
>> That is, if the task fails for some reason (e.g., by means of throwing an
>> exception, interruption, or *ThreadDeath* due to *Thread#stop()*), it
>> needs to be re-spawned. What is the most robust/decent way to implement
>> this?
>>
>> For the records, this is the problem I am dealing with in Log4j:
>> https://github.com/apache/logging-log4j2/commit/56436ad2176eac000d2821690e4373f097b76670#r44892412
>>
>> In a nutshell, we have a wrapper running in the background that calls
>> Log4j *Layout*s to render *LogEvent*s. Though certain layouts can do
>> really strange things from calling *Thread.currentThread().stop()* to
>> throwing an *Error*. These cause the wrapper thread to get killed.
>>
>> I have found work arounds using uncaught exception handlers
>> <https://howtodoinjava.com/java/multi-threading/restart-thread-uncaughtexceptionhandler/>,
>> though I couldn't be sure if this is the right way to do it.
>>
>> Kind regards.
>>
>
> _______________________________________________
> Concurrency-interest mailing [email protected]://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
>

_______________________________________________
Concurrency-interest mailing list
[email protected]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest