Prev: Const correctness (was Re: Oppinion on 'least priviledge', 'const correctness', etc.)
Next: Simple Hack To Get $2500 To Your PayPal Account.
From: markspace on 21 Jul 2010 18:36 Alan Gutierrez wrote: > The OP is perfectly capable of reasoning out the usage of a BlockingQueue. I don't want to sound snarky or anything, but I think piggy-backing with side effects is still something to be very careful of. Will everyone who comes after you be just as aware of BlockigQueue's semantics? And will you remember yourself at 3 am while trying to make some last minute code changes? Other than the obvious (the object being enqueued itself) if you rely on any side effects, I'd document the heck out of them. E.g.: package test; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingDeque; /* Threadsafe */ public class PiggyBack { private final BlockingQueue<String> queue = new LinkedBlockingDeque<String>(); /* Guarded by queue */ private int received; public int send( String s ) throws InterruptedException { int retVal; /* make atomic */ synchronized( this ) { retVal = received += s.length(); } /* received is guarded by this queue, not the synchronized * block above. * do not re-order the update to received below this line. */ queue.put( s ); return retVal; } public int getReceived() { /* must access queue to provide thread safety. * field "received" is guarded by the queue via piggy-backing. */ queue.peek(); return received; } public String recv() { return queue.poll(); } } This may be a silly example, but that's the sort of thing I'm talking about.
From: Alan Gutierrez on 21 Jul 2010 18:53 Lew 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. > > '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. I think you are confusing spurious wakeup, explicitly mentioned in the documentation for `Object.wait`. There is no such thing as spurious interrupts. -- Alan Gutierrez - alan(a)blogometer.com - http://twitter.com/bigeasy
From: Daniel Pitts on 21 Jul 2010 18:59 On 7/21/2010 3:15 PM, Lew 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. >> > > '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.). I think you've misinterpreted something. There are possible spurious wake-ups, but there are *not* spurious interrupts. Object.wait(...) may *return* before the conditions are met, but will not through InterruptedException unless there is a true interrupt. BTW, there *is* an evil way to kill other threads, whether they handle interrupted or not. Thread.stop(throwable); <http://download.oracle.com/docs/cd/E17476_01/javase/1.5.0/docs/api/java/lang/Thread.html#stop%28java.lang.Throwable%29> -- Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
From: Alan Gutierrez on 21 Jul 2010 19:11 markspace wrote: > Alan Gutierrez wrote: > >> The OP is perfectly capable of reasoning out the usage of a >> BlockingQueue. > > I don't want to sound snarky or anything, but I think piggy-backing with > side effects is still something to be very careful of. > Will everyone who comes after you be just as aware of BlockigQueue's > semantics? And will you remember yourself at 3 am while trying to make > some last minute code changes? Well, actually, I'd probably leave quite a few line comments, with a link to this thread in Google Groups (Hello, future me!) My expectation was that the writes to the `List` I put `offer` to the `BlockingQueue` happen before the other thread `take`s from the queue and reads. I'm coming out of this thread with a workable understanding of "happens before" which I plan to not forget, or will make sure I remember before bombing around an delicate concurrent code. Again, your point is taken, tough. I'm expecting that high level abstractions like `BlockingQueue` help me not have to think about things and use them in lieu of `synchronized` blocks. Use of one way volatile reads and writes is definately more difficult to reason out than the use of `synchronized` blocks. The point of this thread was to get a sanity check that I didn't need extra synchronization, that the `BlockingQueue` did what I expected it to do. Now that I know that it does, I'll use it instead of trying to reason out my own form of queuing. Also, I'll note that I'm implementing a write ahead log, so I do expect this bit of code to be the complicated bit, so if it is 3 am, I'll get some sleep before trying to page the project back into my head. This is in its own project so I can isolate the problem and test it. The complexity budget for the project is spent entirely on getting the queue and file append to work correctly. It would be a waste of complexity if this was part of a login form. -- Alan Gutierrez - alan(a)blogometer.com - http://twitter.com/bigeasy
From: Lew on 21 Jul 2010 20:50
Daniel Pitts wrote: > I think you've misinterpreted something. There are possible spurious > wake-ups, but there are *not* spurious interrupts. Object.wait(...) may You're absolutely right - my mistake. > *return* before the conditions are met, but will not through > InterruptedException unless there is a true interrupt. The fact remains that 'InterruptedException' is not about SIGINT or other OS signals but about response to an 'interrupted' condition. JCIP claims that there are two possible correct responses to receiving an 'InterruptedException' - re-interrupt the thread itself (p. 142): "- Propagate the exception... "- Restore the interruption status ..." and the example on p. 144 is specifically about 'BlockingQueue#take()'. He most emphatically does not recommend any of the approaches recommended so far in this discussion. -- Lew |