Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

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

Programming Java threads in the real world, Part 1

A Java programmer's guide to threading architectures

  • Print
  • Feedback

Page 5 of 6

  1. The programmer explicitly "binds" one or more threads to a specific LWP. In this case, the threads sharing a LWP must cooperate with each other, but they can preempt (or be preempted by) threads bound to a different LWP. If every green thread was bound to a single LWP, you'd have an NT-style preemptive system.

  2. The threads are bound to green threads by the user-mode scheduler. This is something of a worst case from a programming point of view because you can't assume a cooperative or a preemptive environment. You may have to yield to other threads if there's only one LWP in the pool, but you might also be preempted.


This threading model gives you an enormous amount of flexibility. You can choose between an extremely fast (but strictly concurrent) cooperative system, a slower (but parallel) preemptive system, or any combination of the two.

So why does this matter to a Java programmer? The main issue is that the choice of threading model is entirely up to the VM -- you have no control. For example, early versions of the Solaris VM were strictly cooperative. Java threads were all green threads sharing a single LWP. The current version of the Solaris VM, however, uses several LWPs. Similarly, the NT VMs don't have the equivalent of green threads, so they're always preemptive. In order to write platform-independent code, you must make two seemingly contradictory assumptions:

  1. You can be preempted by another thread at any time. You must use the synchronized keyword carefully to assure that non-atomic operations work correctly.

  2. You will never be preempted unless you give up control. You must occasionally perform some operation that will give control to other threads so they can have a chance to run. Use yield() and sleep() in appropriate places (or make blocking I/O calls). For example, you might want to consider calling yield() every one hundred iterations or so of a long loop, or voluntarily going to sleep for a few milliseconds every so often to give lower-priority threads a chance to run. (yield() will yield control only to threads running at your priority level or higher).


Wrapping it up

So, those are the main OS-level issues you must consider when you're writing a Java program. Since you can make no assumptions about your operating environment, you have to program for the worst case. For example, you have to assume you can be preempted at any time, so you must use synchronized appropriately, but you must also assume that you will never be preempted, so you must also use yield(), sleep(), or occasionally blocking I/O calls to permit other threads to run. You can't assume priority levels 1 and 2 are different. They might not be after NT has mapped Java's 10 levels into its 7 levels. You can't assume that a priority level 2 thread will always be higher priority than one that runs at level 1.

Subsequent articles will get into considerable detail about various thread-related programming problems and solutions. Here's the roadmap for the rest of the series:

About the author

Allen Holub has been working in the computer industry since 1979. He is widely published in magazines (Dr. Dobb's Journal, Programmers Journal, Byte, and MSJ, among others). He has seven books to his credit, and is currently working on an eighth that will present the complete sources for a Java compiler written in Java. Allen abandoned C++ for Java in early 1996 and now looks at C++ as a bad dream, the memory of which is mercifully fading. He's been teaching programming (first C, then C++ and MFC, now OO-Design and Java) both on his own and for the University of California, Berkeley Extension, since 1982. Allen offers both public classes and in-house training in Java and object-oriented design topics. He also does object-oriented design consulting. Get information, and contact Allen, via his Web site http://www.holub.com.
  • Print
  • Feedback

Resources
  • For a great in-depth look at multithreading in general and the implementation of multithreading both in and with Java in particular, this one's a must. It's required reading if you're using threads heavilyDoug Lea, Concurrent Programming in JavaDesign Principles and Patterns (Addison Wesley, 1997). http://java.sun.com/docs/books/cp/
  • For an intro-level book on Java threading that is less technical but more readable than Lea's effort, seeScott Oaks and Henry Wong, Java Threads (O'Reilly, 1997)
    http://www.oreilly.com/catalog/jthreads/
  • This book is good for those looking into the general subject of multithreading, but doesn't have a Java slantBill Lewis and Daniel J. Berg, Threads PrimerA Guide to Multithreaded Programming (Prentice Hall/SunSoft Press, ISBN 0-13-443698-9)
    http://www.sun.com/books/books/Lewis/Lewis.html
  • Doug Schmidt's ACE framework is a good, though complex, attempt at a truly platform-independent threading system
    http://www.cs.wustl.edu/~schmidt/