|
|
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 7 of 7
FInally, there are tools. In the early years of Java, standalone utilities to help with debugging of thread problems were
popular; more recently, the leading debuggers have incorporated essentially all of this functionality. (For instance, nearly
every debugger, including jdb, supports introspection on threads.) Know what your favorite debugger offers and be sure that it compares well with the alternatives.
The basics of multithreading have changed remarkably little since the early days of the Java platform. One fortunate change, however, is that multithreading has become easier in several important regards.
First, when Java 6 was released at the end of 2006 it brought considerable attention to locking. Locking is an important technique because threads sometimes contend for resources: two different threads might need to update a global variable that tracks how many users are active, or to update a bank account balance. It's very bad, though, to allow the threads to interfere with each other. In the case of an accounting program, imagine a starting balance of $100. One thread tries to debit $10, the other to credit $20. Depending on the exact sequence of operations, it's easy to end up with a final balance of $120 or $90 rather than the correct combination of $110.
Software applications need to guarantee correct results. The most common way to achieve this is with locks or other means of synchronizing the access of different threads. One thread -- the credit one, say, in the example of the last paragraph -- locks the account balance, completes its operation, sets the balance to $120. At that point, it releases the lock to the debit thread, which itself locks the balance, until it has successfully updated the balance to the correct sum of $110.
Locks have the reputation of being difficult and costly, and occasionally they're simply wrong. Improvements to Java 6 and the JVMs that implement locks improved performance and refined programmatic control over them. The result: the speed of multithreaded applications generally improved, sometimes dramatically. (See "Do Java 6 threading optimizations actually work?" for more about threading optimization in Java 6.)
With the release of Java 7 in the summer of 2011, we saw a different kind of improvement to thread programming: removal! One
common application of multithreading has been to answer questions such as, "is there a new file in this FTP repository?" or
"have any results been appended to this logfile lately?" Java 7 includes a filesystem monitor and support for asynchronous
input/output in java.nio.file. So the nio API allows us to directly code file update functionality, thus eliminating one need for programmers to write multithreaded
source.
Closures also reduced the pressure to code with threads. For instance, the java.util.concurrent package includes support for writing concurrent loops (Neal Gafter, 2006).
Current public plans for Java 8 and Java 9 appear to have little direct impact on threaded programming. A major goal of Java
8, scheduled for mid-2013, is more effective use of multicore environments. Expansion of java.util.concurrent.Callable closures will encourage their use (under the formal language label of "lambda") as an alternative to multithreading.
One of the goals for Java 9 is "massive multicore" compatibility. It's not yet clear how this will be effected at the level of language syntax.
One of the most interesting conclusions of the last fifteen years of Java concurrency programming is that threads are not
so much to be avoided as handled with respect. Some teams do best with new java.util.concurrent techniques, or even some of the alternative models I've mentioned. For many teams, though, the best results come from using
threads, but using them with the wisdom of the last decade. This generally involves simple synchronization models, an emphasis
on testability, small and understandable class definitions, and teams that carefully review each other's source.
Cameron Laird began writing Java code before it was called Java and has contributed occasionally to JavaWorld in the years since then. Keep up with his coding and writing through Twitter as @Phaseit.
Read more about Core Java in JavaWorld's Core Java section.
Threads programming
Thread synchronization
Locks and monitors
Testing and debugging threads
Threads & alternatives