Programming Tutorials Browser Tutorials Articles Struts Tutorials Hibernate Tutorials

  Tutorial: Programming Java threads in the real world, Part 5 - JavaWorld - February 1999

Programming Java threads in the real world, Part 5 - JavaWorld - February 1999

Tutorial Details:

Programming Java threads in the real world, Part 5
Programming Java threads in the real world, Part 5
By: By Allen Holub
Has Sun abandoned 'run anywhere'? Plus: Threads and Swing, timers, and getting around stop(), suspend(), and resume() deprecation
'm going to start off this month on a deliberately alarmist note. Feel free to skip to the next section if my foaming at the mouth starts to bother you. Bear in mind, as you read this, that I'm one of the "good guys." I think Java is the best thing since sliced bread. In fact, I've abandoned C++ for Java. Virtually all of my work nowadays centers around Java programming -- either doing it or teaching it. Nonetheless, I'm hoping that some public criticism, as in the following, might encourage Sun to operate in a more responsible fashion than is described here.
Whatever happened to 'run anywhere'?
So, what's so upsetting? It seems Sun has abandoned the "run anywhere" part of its oft-quoted write-once, run-anywhere mantra. I'll explain. The ability to "run anywhere" is predicated on a class file being able to run on any machine that has a Java virtual machine (JVM) on it, and on that VM being able to run any class file it's given. If different implementations of the JVM recognize different class file formats, platform independence is a pipe dream. Microsoft understands this issue very well. That's why it tried to push a nonconforming VM onto Windows. Programs that leverage Microsoft's nonstandard extensions simply are not platform-independent.
This standardization is particularly important in a network environment, where an application installed on a server and distributed automatically must be able to run on all the client boxes, regardless of the VM that's installed on a given box. You can always download a new library -- that's one of the reasons Swing is in the javax (rather than java ) package. Updating the VM itself is another matter. Sun is well aware of this issue. James Gosling himself has often justified changes to the language at the source-code level by saying that no VM changes would be mandated.
In the face of this fact, I was horrified to find that the Java 2 platform (formerly known as JDK 1.2) compiler can create a nonstandard class file format recognizable only to the Java 2 VM. The class file generated by java -target 1.2 will not run on a 1.1 VM. Since you have absolutely no control over which version of the VM is on the client platform, using this switch effectively throws away any hope of platform independence. You'll have to ship your Java application with a version of the Java 2 VM for every platform on which you'd hope to run, and we're back in DLL hell.
Fortunately, the switch is off by default, and you don't have to use it. But even the presence of this switch indicates that Sun is perhaps not as trustworthy as the Java community has been assuming. At a recent Java SIGs meeting hosted by San Jose's Software Development Forum, Gosling stated that even though Java has maintained backward compatibility as it has evolved, Sun has no commitment to this compatibility. He implied that there would eventually come a time where we would all be forced to adopt the new class file format. I can see it now: a Microsoft PR guy waving around a disk, shouting "Here's an official Java application, compiled with Sun's own Java compiler, and it won't run on these Windows, Solaris, or Mac boxes unless you spend hours upgrading an obscure piece of software called the virtual machine. In fact, there's no guarantee that you can even get such an upgrade if you're not running Solaris. Platform independence? Ha!"
The fact that the new nonstandard class file format was sprung on the Java community with no advanced warning or feedback seems to me the worst problem of all. There must be a way to move forward, of course. It's inevitable that the VM spec will change as Java evolves. However, this change should come about through an open process that involves the whole Java community, not a unilateral move on the part of Sun. This no-questions-asked imposition of a new standard strikes me as a betrayal of Sun's commitment to Java as an open standard, and calls Sun's legitimacy as a standards-setting body into question. It seems silly to gripe about Microsoft creating a noncompliant compiler/VM when Sun itself has now done exactly that. I suppose I've been deluding myself into thinking Sun was acting as the steward of an open standard. It turns out that Sun owns the standard, and like Microsoft, does what it feels like whenever it feels like doing it.
Frankly, I can't imagine what would be so important that Sun would be willing to change the VM spec at this point in time. As far as I can tell from experimenting, the generated bytecode is identical to the 1.1 bytecode except for the new version number. (This one difference is enough to prevent a 1.1 VM from loading a Java 2 class file, however.) Speaking as a compiler writer, there are a few annoyances in the bytecode -- mainly workarounds for VM bugs -- but these are trivial matters. I've asked both Gosling and Tim Lindholm (the latter is one of the coauthors of the VM) why the change was made, but neither has given me an answer. Perhaps this ploy is intended solely to render the Microsoft VM irrelevant, since it won't conform to the Java 2 spec. If one of you readers can enlighten me, please send me e-mail; my address is available in the bio below.
Back to threads
On a more prosaic (or perhaps Prozac) note, let's get back to the subject at hand: threads. This month, I want to talk about timers -- objects that help execute some operation at a fixed interval. I'll discuss both the timer that's part of the Swing package and a roll-your-own timer that I've found more useful in some situations.
It's often the case that programs need to execute some operation at a regular interval. Animation loops come to mind immediately, but other applications are legion. Consider the case of a thread that must notify a large list of observers that some event has occurred. Using a timer to notify one observer from the list on each "tick" of the timer can give other threads a chance to run while notifications are in progress.
A simple timed wait doesn't often do the trick, though. For example, each loop iteration in the following example could takes a different amount of time to execute, depending on which way the test goes and how long the database server takes to process requests:
while( running )
{
if( some_condition )
notify_any_observers( FAILED );
else
{
open_a_database();
make_1000_queries();
process_the_results():
generate_a_billion_reports();
notify_any_observers( SUCCESS );
}
wait( FIXED_INTERVAL ); // There is no matching notify(). Just time out.
}
Swingin' threads
The first solution to this problem is the new javax.swing.Timer class. The Timer is designed to be a Swing-specific solution (it's only available if Swing is installed on the client system) to a Swing-specific problem: Swing itself is not thread-safe.
The thread-safety issue is an important one. Swing's threading support is described in depth in a Tech note on the Sun Web site, but to summarize: Swing, like AWT before it, uses a single thread to field all user interface (UI) events that come in from the operating system. This thread dequeues OS events from some sort of event queue, figures out what the OS is trying to tell it, and then notifies any listeners interested in the event. For example, the event thread could dequeue a WM_MOUSEMOVE message from the Windows message queue, and then send out mouseMoved() messages to all the interested MouseMotionListener objects.
These event handler methods (such as mouseMoved() ) actually run on the thread that's dequeueing the OS-level events. This single-threaded approach is a big issue, because the UI is effectively locked while the event handler messages are executing. That is, no OS-level messages (such as button presses) are serviced while listener notifications are in progress. To keep your UI responsive to user input, these event handler functions should be very short and very fast. They must spawn off threads to do time-consuming operations.
To make matters more interesting, none of Swing class's methods are thread safe -- they are simply not designed to handle the case of two threads accessing them simultaneously. The performance hit required to make Swing thread-safe (not to mention the extra complexity) is just unacceptable. The lack of thread safety means that once you start up the Swing event handler thread (by calling setVisible() , pack() , or any other method that makes a window visible), you cannot safely call a Swing method from anywhere but Swing's own event handler thread. (Note that you can safely manipulate Swing objects before the event handling thread starts -- before you call setVisible() or pack() , for example.)
The lack of thread safety is often not an issue because Swing methods are, more often than not, called from Swing's own event handler thread -- remember, all the listener methods run on that thread. For example, a listener's event handler like mouseMoved() might pass a repaint() message to some Component . This operation is safe because mouseMoved() is running on Swing's own thread.
The invokeLater() and invokeAndWait() methods
There are often cases where some thread of your own devising needs to communicate with Swing, however. For example, the main thread of an application could fire up a window, do some stuff, then want to modify the window. Since you obviously need to pass messages to Swing at times other than initialization time, a mechanism has been provided to ask the Swing event-handling thread to execute a block of code for you. You need to encapsulate your code into a Runnable object, and then pass that object to Swing by calling SwingUtilities.invokeLater() or SwingUtilities.invokeAndWait() . For example, a thread could force a window to redraw itse


 

Read Tutorial at: Click here to view the tutorial

Rate Tutorial:
Programming Java threads in the real world, Part 5 - JavaWorld - February 1999

View Tutorial:
Programming Java threads in the real world, Part 5 - JavaWorld - February 1999

Related Tutorials:

Integrating Databases
Integrating Databases
 
3D graphics programming in Java, Part 3: OpenGL
3D graphics programming in Java, Part 3: OpenGL
 
Programming Java threads in the real world, Part 8
Programming Java threads in the real world, Part 8
 
Object-oriented language basics, Part 7
Object-oriented language basics, Part 7
 
Implement a J2EE-aware application console in Swing
Implement a J2EE-aware application console in Swing
 
I want my AOP!, Part 1
I want my AOP!, Part 1
 
I want my AOP!, Part 3
I want my AOP!, Part 3
 
Achieve strong performance with threads, Part 1
Achieve strong performance with threads, Part 1
 
Achieve strong performance with threads, Part 2
Achieve strong performance with threads, Part 2
 
J2SE 1.4.1 boosts garbage collection
J2SE 1.4.1 boosts garbage collection
 
Simply Singleton
Simply Singleton
 
Add concurrent processing with message-driven beans
Add concurrent processing with message-driven beans
 
SAAJ: No strings attached
SAAJ: No strings attached
 
Good, but obsolete
Good, but obsolete
 
Real World HTML Parser
Real World HTML Parser The two fundamental use-cases that are handled by the parser are extraction and transformation (the syntheses use-case, where HTML pages are created from scratch, is better handled by other tools closer to the source of data). Whil
 
Attribute-Oriented Programming with Java 1.5, Part 1
In this article, I will consider the case of a status-bar component embedded in a GUI application. I will explore a number of different ways to implement this status reporter, starting with the traditional hard-coded idiom. Along the way, I will introduce
 
JDBC scripting, Part 2
JDBC scripting, Part 2 Programming and Java scripting in JudoScript Summary JudoScript is a rich functional scripting language, and an easy and powerful general programming and Java scripting language. JudoScript's power comes from its synergy of
 
The ABCs of Synchronization, Part 1
Threads may execute in a manner where their paths of execution are completely independent of each other. Neither thread depends upon the other for assistance. For example, one thread might execute a print job, while a second thread repaints a window. And
 
Commons-Math: The Jakarta Mathematics Library
Commons-Math: The Jakarta Mathematics Library The Java programming language and the math extensions in Commons Lang provide implementations for only the most basic mathematical algorithms. Routine development tasks such as computing basic statistics or s
 
Understanding MIDP System Threads
Describes the multi-threaded aspects of the J2ME application environment. Understanding the interactions between systems threads, user-interface and application threads will help in avoiding MIDlet deadlock.
 
Site navigation
 

 

Send your comments, Suggestions or Queries regarding this site at roseindia_net@yahoo.com.

Copyright © 2006. All rights reserved.