Prev: Const correctness (was Re: Oppinion on 'least priviledge', 'const correctness', etc.)
Next: Simple Hack To Get $2500 To Your PayPal Account.
From: Alan Gutierrez on 21 Jul 2010 17:47 markspace wrote: > Alan Gutierrez wrote: > >> With a terminal value to shutdown the queue, and with the thread >> unexposed to the client, there seems to be no way to send an interrupt >> to the thread, so it becomes the classic unreachable checked exception >> block. > > > See, I'd go the other way. Even though I don't personally know any way > your thread is exposed to a client either, I'd still let an interrupt > kill the thread. Two reasons for this: > > 1) There may be some way a client can send a SIGHUP or similar through > the console, which the JVM might propagate to all threads, for an > orderly shutdown (kill -9 is disorderly and abrupt). There is such a way to accept a SIGTERM, Runtime.addShutdownHook, but it is my understanding that it is up to the developer to implement the orderly shutdown of her own threads. There is no mention of threads being shutdown with interrupt. In the case of my library, you would call a publicly exposed shutdown method that would terminate the worker thread in a fashion that indicated an orderly shutdown. So there are no interrupts sent by the virtual machine at shutdown. Interrupting a thread is something done deliberately. I got to musing about daemon threads, too. I began to wonder if the JVM simply stopped executing statements, or if the overly ambitions stop, start, ThreadDeath mechanism still played some part in shutdown. This program below shows that no interrupt it sent to the main thread and nothing propagates out of the daemon thread, on OSX Sun JVM and on Linux running Open JDK. Compile and run and send a SIGTERM using Ctl+C or kill and the program stops dead. public class SetDaemon { public static void main(String[] args) { Thread thread = new Thread(new Runnable() { public void run() { try { for (;;) {} } catch (Throwable e) { e.printStackTrace(); if (e instanceof Error) { throw (Error) e; } throw (RuntimeException) e; } } }); thread.setDaemon(true); thread.start(); try { Thread.sleep(Long.MAX_VALUE); } catch (InterruptedException e) { e.printStackTrace(); } } } > 2) Another programmer might assume that any thread can be killed with an > interrupt, and might be confused or frustrated when it can't. In this > light, it's just a bit of future proofing and courtesy to make your > thread work in the standard way. Point taken. I'll throw an exception instead. I maintain that this tread is part of the internal state of the library and sending it an interrupt is a programming error, but as a programming error, it should throw an exception the moment the error is detected. -- Alan Gutierrez - alan(a)blogometer.com - http://twitter.com/bigeasy
From: Alan Gutierrez on 21 Jul 2010 17:50 ClassCastException wrote: > On Tue, 20 Jul 2010 21:19:58 -0500, Alan Gutierrez wrote: > >> With a terminal value to shutdown the queue, and with the thread >> unexposed to the client, there seems to be no way to send an interrupt >> to the thread, so it becomes the classic unreachable checked exception >> block. How do you handle the interrupt that never happens? I decided >> that trying again after the impossible was as good as giving into the >> impossible. > > My usual way of handling an "unreachable" checked exception block is > "throw new Error();". Thank you. I'll throw runtime exceptions when I catch an InterruptedException I was not expecting, instead of retrying. I said as much in my last response. -- Alan Gutierrez - alan(a)blogometer.com - http://twitter.com/bigeasy
From: Alan Gutierrez on 21 Jul 2010 17:53 markspace wrote: > Lew wrote: > >> You're mistaken. The assignment in 'methodA()' of 'data' >> /happens-before/ the write to 'set', which latter is synchronized. >> The read in 'methodB()' of 'data' /happens-after/ the read of 'set', >> which latter is synchronized on the same monitor. Therefore the read >> is guaranteed to see the write. > > Brian Goetz calls this piggy-backing in JCIP. (He uses a volatile > variable as an example, which is why I was confused about synchronized > blocks.) And he says it's a dangerous thing to do because it's hard to > reason out these side effect correctly, and hard for maintenance > programmers to spot them as well. So to the OP and others, don't rely > on these side effects. Put all data in a synchronized block and you'll > be less likely to wonder what the heck is going on six months after your > wrote the code. The OP is perfectly capable of reasoning out the usage of a BlockingQueue. -- Alan Gutierrez - alan(a)blogometer.com - http://twitter.com/bigeasy
From: markspace on 21 Jul 2010 18:10 Alan Gutierrez wrote: > Point taken. I'll throw an exception instead. I maintain that this tread > is part of the internal state of the library and sending it an interrupt > is a programming error, but as a programming error, it should throw an > exception the moment the error is detected. A good idea, I think. If you consider an interrupt to be an error, then you certainly want to make note of any interrupts that you find. Other ideas: log the error, but continue running anyway. This might be problematic since you are the logging thread in this case. Consider (also?) writing to stderr. Another one: I've seen code that attempted an orderly shutdown on SIGHUP, but if it caught a second one, then someone is really trying to stop your process (probably a frustrated operator at the console mashing the control-C button). On the first interrupt, continue running (probably record the interrupt though) while attempting an orderly shutdown. On the second interrupt, die immediately. Just tossin' ideas out....
From: Lew on 21 Jul 2010 18:15
Alan Gutierrez wrote: >>> With a terminal value to shutdown the queue, and with the thread >>> unexposed to the client, there seems to be no way to send an interrupt >>> to the thread, so it becomes the classic unreachable checked exception >>> block. > 'InterruptedException' is not about SIGINT or other OS signals, but about the Java method 'Thread#interrupt()'. <http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/ lang/Thread.html#interrupt()> <http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/ lang/InterruptedException.html> There is excellent advice in /Java Concurrency in Practice/ (JCIP. Part of the reason to catch it is that the JVM apparently can throw spurious 'InterruptedException's. Read JCIP (by Brian Goetz et al.). Alan Gutierrez wrote: > There is such a way to accept a SIGTERM, Runtime.addShutdownHook, but it > is my understanding that it is up to the developer to implement the > orderly shutdown of her own threads. There is no mention of threads > being shutdown with interrupt. > > In the case of my library, you would call a publicly exposed shutdown > method that would terminate the worker thread in a fashion that > indicated an orderly shutdown. > > So there are no interrupts sent by the virtual machine at shutdown. > Interrupting a thread is something done deliberately. > Or not, if you get a spurious interruption. > I got to musing about daemon threads, too. I began to wonder if the JVM > simply stopped executing statements, or if the overly ambitions stop, > start, ThreadDeath mechanism still played some part in shutdown. > > This program below shows that no interrupt it sent to the main thread > and nothing propagates out of the daemon thread, on OSX Sun JVM and on > Linux running Open JDK. Compile and run and send a SIGTERM using Ctl+C > Ctrl-C sends SIGINT, not that that is relevant to 'InterruptedException'. > or kill and the program stops dead. > > public class SetDaemon { > public static void main(String[] args) { > Thread thread = new Thread(new Runnable() { > public void run() { > try { > for (;;) {} > } catch (Throwable e) { > e.printStackTrace(); > if (e instanceof Error) { > throw (Error) e; > } > throw (RuntimeException) e; > } > } > }); > thread.setDaemon(true); > thread.start(); > try { > Thread.sleep(Long.MAX_VALUE); > } catch (InterruptedException e) { > e.printStackTrace(); > } > } > > } markspace wrote: >> 2) Another programmer might assume that any thread can be killed with an >> interrupt, and might be confused or frustrated when it can't. In this >> light, it's just a bit of future proofing and courtesy to make your >> thread work in the standard way. > Alan Gutierrez wrote: > Point taken. I'll throw an exception instead. I maintain that this tread > is part of the internal state of the library and sending it an interrupt > is a programming error, > Or a spurious 'InterruptedException'. > but as a programming error, it should throw an > exception the moment the error is detected. > Unless it was a spurious exception. -- Lew |