- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
// Assume everything is initialized
Admin
Whooooooaaa there. I see how you could jump to the conclusion that I was talking about all the code, but I was actually referring to the snippet in the current thread (which you can't see because of the wonderful messageboard software):
This WTF as a whole definitely deserves its title 150% - it made my jaw drop. I get your point about Tomcat deployment unloading - I haven't worked with Tomcat for a while unfortunately.
But I would like to learn something from this..... so lets assume, for a moment, that the sleeping is waiting on something that is guaranteed to complete in a timely fashion.... and for some reason we needed to wait for it. Wouldn't this be an ok way of handling it, if we threw an unchecked exception?
Or would it be much better to use some kind of Join functionality with the thread (assuming we started the thread ourselves)?
Admin
After starting the db-worker-thread (if I may call it that), InboundMessageHandler sleeps until the operation has succeeded, i.e. the message has been added to the database.
This effectively means that only one db-worker-thread per InboundMessageHandler instance is ever running.
InboundMessageHandler does not feature any kind of notification system, i.e. db-worker-thread does not notify the InboundMessageHandler instance that it has succeeded. Therefore, it's up to the InboundMessageHandler instance to find out if this is the case.
To achieve this, InboundMessageHandler sleeps for 10ms, looks at the database to see if rowcount has increased and if not sleeps again for 10ms, looks again, etc.
Yes, this is bad and the main WTF of the article.
But it also means it is ok to ignore the InterruptedException, since it only means that the InboundMessageHandler instance will in one round get less than 10ms of sleep. It wakes up, yawns, looks at the alarm clock, shakes its head, checks if rowcount has increased, and if not, goes back to sleep.
There are cases when a "do nothing" is ok, this is one of them. Good reading in this case is actually http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html: the sentence "nor reassert the thread's interrupted status" is the key, since this is exactly what InterruptedException does. It looks around, finds the situation to be unchanged, and goes back to the state before the InterruptedException was caught.
So, although the code is quite a big WTF, the "//do nothing" is completely ok.
Admin
Well that's stupid and pointless.
Admin
It isn't and your link actually say exactly the opposite of what you claim:
The most applicable example for this case would be:
public Task getNextTask(BlockingQueue<Task> queue) { boolean interrupted = false; try { while (true) { try { return queue.take(); } catch (InterruptedException e) { interrupted = true; // fall through and retry } } } finally { if (interrupted) Thread.currentThread().interrupt(); } }
Admin
It doesn't crash so it's fine, right? lol
Admin
I wonder what would happen if the transaction deleted (or updated) rows, rather than inserting them?
Admin
Yup, it's not like exceptions are expensive or anything.
Admin
TRWTF is JDBC do not have async APIs.
Admin
Yes!
I'd like to add that a good way of generally handling unexpected (or impossible) InterruptedExceptions is to do this:
This pattern has a few advantages..
Cheers guys.
Admin