Howardism Musings from my Awakening Dementia
My collected thoughts flamed by hubris
Home PageSend Comment

Threading Gotchas in Java

Repeat the mantra with me, Threads are fun. Threads are safe. OK, now let's list some of the falsehoods, gotchas and little known facts associated with threading on Java. This page is just a collection of stuff associated with threads and may not be that connected (but these notes have proved useful to me).

Each of the following are wrong…

  1. Variable assignment is safe in Java. While assignment to an int or a boolean is atomic, assigment to anything else (including doubles and longs) are not.

  2. Java threading is OS independent. This is kind of false as well. Sure, all of the keywords and whatnot are available of every OS, each OS behaves slightly differently. For instance, NT doesn't have enough priority levels that Java offers, so if your code assumes that priority 2 is higher than priority 1, you may be mistaken. This is also an issue if you want parallelism where two threads are actually running concurrently.

  3. Threads are preemptive. Once again, this is kind of false. On some JVMs, you could create a thread, but it may either run until conclusion or not run until the parent thread runs to conclusion. The best approach is to call sleep() or block on some IO or something to make sure that other threads will run.

  4. Synchronization doesn't take any time. While newer JVMs with their improved threading capabilities have made synchronization execution shorter, it still takes time. Not only that, but locking out code with the synchronized keyword starts to limit the JVMs ability to effectively manage thread execution.

  5. Sections of Java code have individual locks. Actually, locks (or mutexes) are associated with an Object. Using the synchronize keyword around some code doesn't create a lock for that section. Instead it acquires the lock associated with the Object instance containing that code. For instance, if you had two synchronized methods, only one thread can execute either of those methods.

Whence `stop`?

Once upon a time, I was lulled into thinking that the stop() method was safe and fixed when Java first came out. Granted, there are times when it could be used safely, but its original inclusion was problematic. Look at the following:

synchronized void myMethod() {
    Thread.currentThread().stop();
}

What happens when this method is called? The thread acquires the lock and then stops… but the lock is never released. The solution is to simply finish the thread or have the thread abort itself. My personal fav is to simply have a boolean value called keepRunning that the thread regularly checks to see if it should continue or bail out.

Threads as Timeouts

I recently had a problem where executing a call to URL.getContent() took a minute to timeout when the remote host was not running. This was causing the main program to appear sluggish. My first attempt was to establish a java.net.Socket connection and to implement the HTTP protocol, however, even setting the Socket's initial timeout to 1 millisecond took up to 30 seconds to realize that the remote side was just not going to respond.

Of cource the reason for this is that TCP connections could actually take some time to work its way through the Internet to the remote server. However, on a LAN, this was seen as unacceptable. My solution was to call the getContent method in a subthread.

The parent thread would then wait() on the child thread but with a short timeout, and if the child did not have the data by this point, it could throw a "timeout" exception and continue on. When the child eventually timed out, it would end and be cleaned up in the background.

Tell others about this article:
Click here to submit this page to Stumble It