File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Threads and Synchronization and the fly likes How to kill a child thread from its parent? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "How to kill a child thread from its parent?" Watch "How to kill a child thread from its parent?" New topic
Author

How to kill a child thread from its parent?

Ben Ethridge
Ranch Hand

Joined: Jul 28, 2003
Posts: 108
Hi, everyone.

I do a lot of java/j2ee work, but not much with the Thread class. I wrote a simple thread manager, which spawns two threads. Each of those threads then goes into infinite loops, with a Thread.sleep(3000) in the loop.

I'd like to know if there's a way to kill one of the child threads (but leave the other one running) from the parent thread that spawned them.

In Eclipse, I first tried to simply 'Terminate' one of the child threads, but alas, that terminates ALL the threads, children and the main parent.

I've tried a child2.stop() in the parent thread (which has a reference to the Thread child2) but that crashed my Eclipse IDE pretty bad, so I'm not going to try that deprecated method again. I guess they MEANT it when they deprecated it

I also tried child2.destroy(), but that threw an error....and didn't kill the child anyway.

I tried child2.interrupt(), hoping that would force child2 to throw some kind of interrupt exception, but no luck there.

In unix, it's quite simple to kill a given process. What's the trick to killing child threads in java?

One caveat: child2 can have a deep call stack, i.e. lots of object.methods called pretty deeply, so it may be, say, off in a jdbc call at the time I want to kill it.

Ben
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18505
    
  40

Unfortunately, the recommended way to cause a thread to exit is to "arrange for it to exit" -- meaning setting some kind of "exit" flag that will be checked by the thread periodically.

The interrupt() does indeed cause certain methods to exit with an InterruptedException, but since it is a checked exception, I am willing to bet that you probably just ignore it and tried again. Furthermore, it is not guaranteed to work. For example, on Windows, I/O is not interruptable.

The stop() method is deprecated because of the way it works, it causes the thread to throw a throwable that is not checked (or even caught, as most developers didn't know about it). This had the effect of causing threads to exit in states that were not usable -- and in rare cases, even messing up some JVM internals.


So... no short cut to do this. You have to design an exit strategy for your child thread.

Henry


Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
Henry, I used a while(running) boolean to stop loops in the run() method for a long time, but then realized interrupt() and interruped() seem just right for the job. Is that a preferred way to signal the loop or sequence of steps that it should terminate?

For example, I have a thread that does a blocking read, then some expensive formatting on the result. I give up on the read after a while in the "main" thread and interrupt the one waiting on the read. It doesn't do a thing for the blocking read, but does tell the worker not to bother with the formatting.


A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18505
    
  40

Originally posted by Stan James:
Henry, I used a while(running) boolean to stop loops in the run() method for a long time, but then realized interrupt() and interruped() seem just right for the job. Is that a preferred way to signal the loop or sequence of steps that it should terminate?


This is only opinion... It is perfectly fine to use the interrupt flag as your exit flag, but most cases are not that simple. The interrupt flag may not be set in some cases, like in a wait(), sleep(), or join(). The interrupt flag may also be cleared -- if you call interrupted().

My preference is to not use interrupt() at all, and design the system to check at regular intervals. For cases where this is not possible, I will use the interrupt, but keep a separate flag.

Henry
Ben Ethridge
Ranch Hand

Joined: Jul 28, 2003
Posts: 108
Originally posted by Henry Wong:
Unfortunately, the recommended way to cause a thread to exit is to "arrange for it to exit" -- meaning setting some kind of "exit" flag that will be checked by the thread periodically.

The interrupt() does indeed cause certain methods to exit with an InterruptedException, but since it is a checked exception, I am willing to bet that you probably just ignore it and tried again. Furthermore, it is not guaranteed to work. For example, on Windows, I/O is not interruptable.

The stop() method is deprecated because of the way it works, it causes the thread to throw a throwable that is not checked (or even caught, as most developers didn't know about it). This had the effect of causing threads to exit in states that were not usable -- and in rare cases, even messing up some JVM internals.


So... no short cut to do this. You have to design an exit strategy for your child thread.

Henry


Not sure what you mean by "periodically". Do you mean that I should scatter if-conditions throughout my code at various strategic points? or do you mean somehow(?) send a signal after x number of seconds?

How would I have ignored the interrupt? I don't think I added code to intentionally ignore it.

Could you possibly provide a short "exit strategy pattern" example?

Ben
Ben Ethridge
Ranch Hand

Joined: Jul 28, 2003
Posts: 108
This was a pretty good article explaining the issue:

http://www.forward.com.au/javaProgramming/HowToStopAThread.html

Notice under the "Suggested Methods for Stopping a Thread" heading, it shows the suggested code. I imagine this is what you meant by "periodically".

The potential issue (question/problem) I have with this is:

What if the code is executing down in the repaint() method? If that method has not been "custom-coded" somehow to handle the thread-stopping logic, will the interrupt() signal that method to abort? I'm betting it won't coz it's not in the try/catch for the InterruptedException.

After reading the article, this appears to me to be a major design flaw in the java language, that everyone's just working around as best they can, yes?

Ben
Peter Chase
Ranch Hand

Joined: Oct 30, 2001
Posts: 1970
Originally posted by Ben Ethridge:
After reading the article, this appears to me to be a major design flaw in the java language, that everyone's just working around as best they can, yes?


It's difficult to say, I think.

In some cases, where you know it would be just fine to forcibly kill a thread, it's a pain that you can't. But, on the other hand, it is in fact rarely a good idea to do so, as the thread doing the killing often has no idea what the thread being killed might be in the middle of. A co-operative scheme, based on interrupt and/or stop flag, is much safer.

I do think it is pretty definitely a flaw in Java that some of the API methods (particularly I/O) that can block for a long time do not check for interrupt and throw InterruptedException.


Betty Rubble? Well, I would go with Betty... but I'd be thinking of Wilma.
Ben Ethridge
Ranch Hand

Joined: Jul 28, 2003
Posts: 108
Originally posted by Peter Chase:

...the thread doing the killing often has no idea what the thread being killed might be in the middle of.


How is this any different than killing a unix process?

Ben
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18505
    
  40

Originally posted by Ben Ethridge:

How is this any different than killing a unix process?

Ben


Unix processes are more or less "self contained" in the OS. As for items that are not contained, like open files, sockets, IPC's, etc., they can be closed.

Threads in the JVM are parts of the process. (The JVM is one unix process to the OS) They synchronize with each other, and changes the state of objects. If the thread that changes the state to the certain value, and supposed to change it back at a later time, doesn't because it gets killed -- then what happens to the program.

This is not to say they can't be killed. It is just that they are so tighly integrated, that care should be taken.

Henry
Ben Ethridge
Ranch Hand

Joined: Jul 28, 2003
Posts: 108
I was speaking more conceptually and philosophically than technically. It's the "less" in the "more or less" to which the analogy applies, i.e. you can do a lot of damage with a kill -9, if "care" is not taken...and if I remember my unix syntax You have to know enough about the technical details of the process (or thread) you are killing, to know whether it will or won't cause harm.

The problem with java, unlike unix, is that the designers decided that they know better than the users what they should and should not be allowed to kill easily, so they shut off the stop switch coz it didn't work.

If you read Alan Cooper's (the father of VB) book "The Inmates Are Running the Asylum", it is one of the main points of the book. Essentially, if YOU are able to "start" something, YOU should have the power to "stop" it.

With java, it's like a car that has an ignition switch into which you can put a key, and start the car. No problem there. But if you try to turn off the car with the key, the engine catches on fire. So, the manufacturer recalls all the cars and disables the engine-stop functionality. They send an addendum to the instruction manual to all the owners, that if they ever want to turn off the engine, they have to open the hood, pull off all the spark plug wires, and then disconnect the battery.

Mr. Cooper's point, as I understand it, is that in other engineering disciplines (like, say, automobiles), such "workarounds" are completely unacceptable. Who would buy a car like that? In the world of software engineering, such workarounds are considered the norm and are "accepted practice". (Just look at the responses to this forum thread.)

Why is this important to you? Because the software tools you use (including languages such as java) would be much more powerful in your hands if all software engineers kept his points in mind when designing/writing software...including MS Windows, and including java.

Ben
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18505
    
  40

The problem with java, unlike unix, is that the designers decided that they know better than the users what they should and should not be allowed to kill easily, so they shut off the stop switch coz it didn't work.


Ben,

Don't want to belittle your point, since you feel incredibly strong about it.

The designers didn't "shut off the stop switch", they merely deprecated it. Meaning they mentioned that it didn't work, they told you why, they recommended some work arounds, and they flagged it so that compilers will warn you about it.

The stop() method still works, and works just as well as it did before it was deprecated -- meaning not very well.

Henry
[ November 02, 2006: Message edited by: Henry Wong ]
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18505
    
  40

One more point... If you don't run your program in an IDE, which sometimes does funny things for debugging. Or in a web/app server, which have tons of other threads going on. You may never have a problem with stop().

For standalone programs, with only a few threads, it is actually pretty stable. In fact, I have never encountered a problem during the early days.

Henry
[ November 03, 2006: Message edited by: Henry Wong ]
David Nemeskey
Ranch Hand

Joined: Nov 08, 2006
Posts: 52
Ben,

I think your analogy is not necessary correct. In my opinion it has to do with the difference between "whole" and "part". A process (or rather, the java program) is a "whole", and its threads are a "part". Just as a car is a "whole", and a tyre, the steering wheel, etc. are "parts".

Is it a good idea to, say, kill the brakes when the car is running? Disable the steering wheel? Stop one of the wheels? More importantly... can you do it in any car? Of course not.

"Parts" have to cooperate to produce a "whole". It also means that the whole has a control over its parts, and (most of the time ) knows what they do. It's not like another program can start a thread in your process. If you own your program, you can write the threads in a way so that they can be stopped safely.

I agree with you, that sometimes it is bothersome, and it would be much easier to have a "kill" option. But I do not think it is such big a problem.

And finally, this is (just) my belief! ...At least for now.

David
Ben Ethridge
Ranch Hand

Joined: Jul 28, 2003
Posts: 108
Sorry, but I don't agree. I see no effective difference between killing a thread from the parent thread (or the java virutal machine itself, i.e. one of the child's ancestor threads), and killing a unix child process from its parent process (or the unix "machine" itself i.e. one of the child's ancestor process).

The unix authors could just as easily deprecated the kill command, and forced everyone to write self-kill logic in each threaded app, to protect them from killing apps that should not be killed. I don't see how unix process are any more or less "self-contained" than java threads. Both are dependent on the skill of the developer. By that I mean, unix processes are simply running "threads" of code: The app you coded, third-party libs or unix kernel itself. I see no essential difference. Sure, if you kill the wrong thread, you can lock up your app or the entire operating system, but that would be your fault for not knowing your app's behavior well enough. For the most part, the unix authors protected unix from your app. I've very, very seldom seen the kill of an app process take down unix, and I've had to kill many apps I didn't write...although sometimes, I admit I was holding my breath when I executed the kill command.

The jvm should protect itself from your app to an equal degree, in my opinion. Apps should be interruptible and stoppable from OUTSIDE the app, without special custom logic INSIDE the app. Otherwise, we're all moving backwards, not forward, in terms of state-of-the-art operating systems. (I consider the jvm to be an operating system within an operating system - thus the term "virtual machine".)

Also, it is not real-world to think that everyone "owns their own program" these days, if that's what you meant. In fact, I'll hazard a guess that about 95% of the time programmers are asked to hook into and communicate with code that is out of their control, from a code maintenance point of view (i.e. other apps in the company and third-party libs and frameworks)...even if they did have the time to refactor the app to gracefully accept a "stop" command.

To me, this just boils down to common sense: if you have an exterior start mechanism, you should have an exterior stop mechanism AT THE SAME LEVEL as the start mechanism.

To me, you both are sounding as if you are simply making excuses for a design flaw in java. Read the guy's article above (near the beginning of the article). This isn't just me saying this.

However, if you can give me a good technical reason why this cannot be done in java, a reason that does not simply expose another design flaw in it, then I'm all ears.

Ben
David Nemeskey
Ranch Hand

Joined: Nov 08, 2006
Posts: 52
It's no problem that you don't agree. I understand your reasoning, but I cannot agree with it fully.

I think threads and apps should not be confused, or made equal. They have very distinctive features, even if they may seem alike.

An application is a whole program: it is immediately visible to the OS, it has its own memory area, secured by the OS, etc. It can also compete with other apps, usually w/o any problems (and it is how modern multitasking is designed).
A thread, on the other hand, is just a "part" of something greater: it shares its memory with other threads, so it must cooperate with them to work at all.

So I think it does not make sense, to expect them to work in the same way. In the same way, you cannot kill your lung or stomach, but you can kill someone else.

So, I think you are wrong, when you say that it was a design fault. It is a design decision (that they do not replace the stop() method). You may like it or not -- in the same way, as you may like the garbage collector or not. I, for one, could just use manual memory management sometimes, but I can't. Is this a design fault then?

If I could find an explanation, why it is not possible, now that would mean it is a design fault. However, I believe this was a decision, and you should ask James Gosling and co. about their reasons.

Anyway, now for the JVM being like an OS, the DOS was also "like an OS"... I think your concern will be much more appropriate if the MVM comes out. If it ever comes out...

Cheers,
David
[ November 17, 2006: Message edited by: David Nemeskey ]
Ben Ethridge
Ranch Hand

Joined: Jul 28, 2003
Posts: 108
No problem. We'll agree to disagree.

As for the garbage collector, yes, I think it has a severe design flaw for essentially the same reason. You can "construct" an object whenever YOU say so, i.e. you have full control over that, but you cannot "destruct" the object whenever YOU say so. Garbage collector decides when that will occur, i.e. once again the "start" and the "stop" are not controllable AT THE SAME LEVEL.

So, imagine you decide to use java for your real-time app, say your new X-fighter (airplane), to control the ailerons, elevator and rudder. (I used to be a flight instructor, so I know a bit about this particular "app".) You, the pilot, decide to input some left aileron to miss that radio antenna that someone suddenly put up in front of you. Oh, S*^#!

Right at that same second, the garbage collector, knowing more about what need to be done when, than the you, the pilot, you who are now frantically moving the unresponsive yoke back and forth...and knowing more than the poor java app programmer, who did the best she could by giving the almighty GC "hints" in the form of System.gc()'s that the GC, by design, is free to ignore. (Right? I was taught that System.gc is not a guarantee to collect at that point, right?)

The GC, in its infinite wisdom...wisdom that Gosling or someone at his level of knowledge coded into it (maybe he was in a hurry and didn't have time to write a really good GC? If so, that's forgivable. Been there myself many times )..., anyway the GC decides that NOWS the time to collect the 100,000 objects that have been growing memory, objects it didn't have time to collect before, because so many objects were being quicky created as the pilot desperately attempted to maneuver through that bad thunderstorm a couple of minutes ago.

This, that the GC (the jvm programmer) knows more than the pilot (the user) is essentially one of Alan Cooper's points in his book, and yeah, I'd call that a "design fault". Once again, this isn't just me saying this. See "Garbage Collection":

http://www.cs.virginia.edu/~mpw7t/cs655/nojava.html

Note the date in the article above, because the good news is that it looks like, on this one, they've decided to fix the flaw:

http://java.sun.com/developer/technicalArticles/Interviews/Bollella_qa2.html

http://www.onjava.com/pub/a/onjava/2006/05/10/real-time-java-introduction.html

(Again, note the article dates above.)

Now, if they'd undeprecate the .stop(), I'd be a happy coder, and I'd love to know the technical reason that they can't, coz then maybe I could work around the crashes it's causing me in Eclipse.

Now, why should YOU (the java community) care about any of this?

Because Mother Nature loves efficiency, i.e. because if you don't, then some other language, a new, more elegantly designed language with less "scar tissue" (see Alan Cooper book above), a language that was not initially designed to run your toaster oven, a language written by some team with no significant investment in java, is going to come along and kick Java's a**. This would make me very sad, coz I've now invested so many years in it.

So, now that java's been open-sourced by Sun, will someone please, please, please undeprecate the .stop()...and make it work as it was originally intended?

Ben
 
Don't get me started about those stupid light bulbs.
 
subject: How to kill a child thread from its parent?
 
Similar Threads
Parent Thread stops then does child thread also stop?
RMI + Thread: perform searching on different worker PCs
best way to kill ?
is it possible that a parent thread dies before the child ?
Determining where static is running