Saturday, August 18, 2007

Managing threads in your Java (or other) applications.

In my previous blog entry, I went through techniques to create a thread safe class. However, I also pointed out that correctly implementing thread safety in your code is only part of solving the problem. The first and most important step in creating a thread safe application is to lay down the threading model for your application. There are multiple ways of insuring thread safety, and it is critical to make the right choices early in the process because a lot of the code you write will depend on these choices. I would even say that it is more important to get these choices stabilized than most other aspects of the design of your application. Multiple threads complicate your application significantly, but if they are necessary to your application (e.g. responsiveness of your Swing application), you should not forego them first, to add them later. Adding thread safety to existing code, is a lot more error prone than starting from scratch with thread safety in mind. In this entry I will go through a few ways to handle threading in your application.

First, we are going to make the assumption that you have divided you application into components. These components can so basic as model and presentation components, but you most probably grouped your design elements into larger blocks of functionality with well defined responsibilities. We’ll also assume in our definition of a component that they have a certain size and several access points. For example, a Swing component is not a component in this sense, a component handling all communication with an external data source would qualify. Usually, only components are worth considering when putting together the threading model of your application. What you want to define is what happens at the boundaries of your component, what happens inside the component should in essence be irrelevant to your application (This is not true when it comes to resource management, but for now we will keep that assumption). There are three basic ways to manage threading on the boundaries of your application, all other ways I’ve seen so far could be expressed in terms of these.

- Thread Confinement.
- External synchronization mechanisms.
- Internal synchronization.

Thread confinement is probably the easiest to implement, and should be one of the first things to cross your mind. The principle of thread confinement is that you only allow predefined threads to access your component. The Swing framework is an obvious example of thread confinement; you are only allowed to access Swing classes from the Event Dispatch Thread. Implementing this is fairly easy and the only synchronization point you have to worry is when other threads need to access the component threads to post a request. When I say component threads, it is to imply that unlike Swing you are not forced to have only one thread. For example, you can divide your component internally and define which component thread is allowed to access which part, then depending on the nature of the request from the client you would dispatch it to the appropriate thread. This tends to make things a lot easier when coding your component because you do not have to worry so much about synchronization on each part of your code, because you know exactly which thread is going to access what. This might also perform pretty well because there is no thread contention either. Of course, this is more or less reverting to a sequential execution model with all the limitations that this implies. The most obvious ones being possible resource starvation and poor scalability, if one client post a big job on your component thread, then all the other clients might be starved out and your component becomes the point of contention of the entire system. Another problem arises because the integrity of your component depends on well behaved clients, if a client decides to call elements from their own thread; there is probably little you can do about it short of putting checks on all access points of your component (hint: use aspects). Using thread contention makes things easier when coding your component and it does make sense to use when your component is limited by other resources anyway. For example, a printer driver can never go faster than the printer, so why bother having a whole bunch of threads accessing it when only one can actually print.

An external synchronization mechanism is a little bit like thread confinement, but you don’t define specific threads to be the only ones able to enter your code. In this case, you provide the clients with a lock they can take prior to accessing your component. For example, if you have a component providing data to all other components, imagine the data is structured as a database and you have data tables, you could provide a lock() method on a table object. Any client wanting to access that table would have to first get the lock() on the table and release when done. This would ensure that only one thread accesses this table concurrently. However, this might not be enough. What if a client wants to operate on three tables and it needs exclusive access to all of them. In that case, you could introduce a lock manager that could have a lockTables() method. This is probably the most useful feature of an external synchronization mechanism; it allows your clients to synchronize access to several resources in your component in a single operation. In some cases, this might be your only option because the client is the only one with the knowledge of what it is going to access, and you need to ensure data consistency across all accesses. This also (potentially) gives a finer grained resource management than thread confinement, the client actually tells you what it is going to access potentially giving you the possibility to optimize your mutual exclusion strategy. Plus implementation wise you can start with a lock manager, that is just a global lock and if that gives sufficient performance stop there. The downside is that you force the clients to first remember to take a lock, then to tell you what they are going to access. This can be error prone, what if the client forgets to lock everything it needs or someone changes the code to access a new resource but forgets to update the locking call?

An external synchronization mechanism that you expose to your clients does not have to actually lock anything; you could try and implement the hipped transactional memory or some transactional scheme. What that means is that several client threads are allowed in the component, and they all do what they need to do and when done they try to commit. Committing will:

1. Check that no other thread changed any of the data accessed by the committing thread.
2. Make the changes from the committing thread visible to other clients.

If step 1 fails, an option is to tell the client to rewind and try again, if it so desires. This gives an all or nothing semantics much like databases which can be very useful in some instances. This should also give a very good throughput because no thread is ever pre-empted from working by any locks (except when it needs to commit). However, if too many threads are walking on each others feet, you will end up doing a lot of work twice or actually never manage to get it done, leading to starvation for some clients. Another advantage is that the client does not need to tell in advance what it is going to access; it just needs to mark the limits of the transaction.

Using internal synchronization, you do not expose any synchronization mechanism to the clients and allow any number of threads to concurrently make calls to the component. It is then up to you to synchronize the internals of your component to ensure correctness. This is the easiest for the clients since they do not have to worry about any threading issues. However, internally in your component you’ll have to synchronize everything that several threads can touch. One example of this is the first few versions of the AWT framework, which actually allowed any threads to call it. This was however short lived, because the developers quickly found out that this was way too hard to get right and they moved to a thread confinement design instead. While this approach can offer many advantages in terms of scalability and ease of use for the clients, experience tells that it should be limited to fairly simple components. Once a component has reached a certain size, the task becomes overwhelming. For the client, the main problem with this approach is that it cannot assure consistency across multiple calls to the component like the external lock could.

So what to choose for your components? Well, there really isn’t any simple answer to that. What you should choose for a component is not only influenced by the component itself, but also by the application as a whole. You need to make sure that no component will be a bottleneck when going live. Threading allows for better scalability, but they also complicate things and if your thread spends more time synchronizing than working then the advantages are effectively nullified. Each technique for threading presented here has advantages and disadvantages that need to be balanced. Also there are limitations, like consistency across multiple calls. When it comes to it, the most important thing might be, to actually have a plan; you won’t get it a 100% right from the start, but it is a lot easier to make changes to a predefined well known model, than to a de facto model that arose from the implementation. As for all software, keep it simple and don’t be a feature/performance freak, if you don’t need it now don’t implement it, if you think a single thread can do it, keep it to that.

Saturday, August 11, 2007

Making your Java Class thread safe.

Thread safety is a very hot topic for Java programmers right now. At the JavaOne 2007, I noticed a fairly large number of technical sessions related to dealing with multithreaded code. It seems to be mostly due to the evolution of the hardware rather than a shift in paradigm in the software world. While most servers have been multiprocessor systems for a long time, most desktop computers are also starting to offer options for concurrent execution of programs, be it using multiple CPUs or a multiple core CPU. So while developers working mostly on the server side of things have been focused on building multithreaded systems, desktop developers are now also forced to take multithreaded designs into consideration. Defining the threading model for your application is probably the most important step you can take into making your code thread safe. The actual coding actually only comes second in my opinion, you need to have your threading model down beforehand so you can actually get your code right. The reason for that is that there are a lot of different ways to make your class thread safe, and you can only pick the right one if you know the thread access pattern to your class.

So what does it mean to have a thread safe class? A thread safe class is a class that guarantees the internal state of the class as well as returned values from methods are correct while invoked concurrently from multiple threads. There is an important distinction to make, just because a class is thread safe, does not mean that you cannot introduce any concurrency problems using it. The most common example of this can be found in the collections framework, consider the following code:



import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

public class ThreadUnsafeBookStore {

private final Set<Book> availableBooks =
Collections.synchronizedSet(new HashSet<Book>());

public boolean buyBook(Book book) {
if(availableBooks.contains(book)) {
// Order book ...
if(--numberRemainingCopies == 0) {
availableBooks.remove(book);
}
return true;
} else {
return false;
}
}
}


We are using a synchronised Set to keep track of the available books at this particular bookstore. Basically any number of threads can access the availableBooks Set concurrently and the set will maintain a consistent internal state, however that does not mean that the state it represents in the book store will remain consistent. Imagine two customers trying to buy the same book at the same time, yet the book store only has one copy left. Two threads enter the buyBook() method and one possibility for the order of execution is as follows (thread one is green, the other is red):


availableBooks.contains(book)
Order book ...

availableBooks.contains(book)
Order book ...

if(--numberRemainingCopies == 0)
availableBooks.remove(book)
return true;

if(--numberRemainingCopies == 0)
return true;



In this example, both customers managed to order the book, but there will be one unhappy customer because in the physical world the bookstore only has one copy. There is a couple of ways to fix this, one is to declare the buyBook() method synchronized in which case only one thread at a time would be able to execute this method. However, that is somewhat misleading synchronization, synchronizing the method means you are taking the Monitor on the BookStore instance, but that is not the resource you are actually worried about. The resource you need to restrict concurrent access to is the availableBooks Set. The following code is more explicit about that.



import java.util.HashSet;
import java.util.Set;

public class ThreadSafeBookStore {

private final Set<Book> availableBooks = new HashSet<Book>();

public boolean buyBook(Book book) {
synchronized (availableBooks) {
if (availableBooks.contains(book)) {
// Order book ...
if (--numberRemainingCopies == 0) {
availableBooks.remove(book);
}
return true;
} else {
return false;
}
}
}
}


This code clearly indicates that the synchronized block of code is accessing the availableBooks resource and we need to protect this resource from concurrent access. A side effect of this is that you do not need to use a synchronized set anymore (if you put all accesses to it inside a synchronized block as shown in buyBook()). This is also more flexible when managing threaded access to the BookStore class. Imagine that you have several resources that you need to protect in your class, then synchronizing on the BookStore instance is inefficient, because you might only access one of the resources in one method, while another method uses another resource. Synchronizing on the BookStore instance, only one thread at a time can work, but synchronizing on individual resources several threads can work on the bookstore concurrently as long as they don’t access the same resources inside the bookstore.

The synchronized keyword is a fairly straightforward, but powerful, tool to make your classes thread safe. However, it is not the only option you have available; let us look at another example of an unsafe class, this time dealing with visibility.



public class ThreadUnsafeBean {

private int x;

public int getX() {
return x;
}

public void setX(int x) {
this.x = x;
}
}


Right now you might be wondering what could possibly go wrong with this code, certainly it doesn’t get more basic than this. The problem resides in the Java memory model, which allows the JVM to optimize a number of things, especially when it comes to memory accesses. Reading something from memory is expensive in a program, especially when you have all these nice registers and caches around in your CPU. Each thread is allowed to have its own cache of sorts, so for the following sequence of calls you could run into a problem.

setX(0)
setX(1)
getX()

getX()

Thread one (in green) could reasonably expect the getX() method to return 1, since thread 2 (in red) set the value to 1 previously. However, because the JVM is allowed to optimize access to field values, it can retrieve the value of x from the threads own cache which at this point contains the value 0. This code is so simple and appears in so many programs, how come we don’t get that error more often? Well, mainly because most JVM implementation will only optimize this for systems with many CPUs or hardware that has a memory management that supports this kind of optimizations. For example the x86 architecture has a memory management model that is quite conservative, so you’re unlikely to see this problem on that platform. However, that might change and if you move your application to a platform that does more memory optimizations, this problem might show up a lot more often. One of the ideas behind Java is write-once run anywhere, and that is actually possible since the Java memory model is the same independent of the underlying hardware platform or OS. So how do we fix this code?

One option is to declare the getX and setX methods as synchronized, because in addition to making sure that only one thread at a time can execute the method, the thread will synchronize its cache with the values stored in memory. This will work and you are assured that you will always get the right value of x. This is however not the best solution because this could cause quite a lot of thread contention and is overkill because you don’t want to restrict access to the method to one thread at a time, you just want the value x to be visible to all threads at all time. Therefore, consider the second option shown below.



public class ThreadSafeBean {

private volatile int x;

public int getX() {
return x;
}

public void setX(int x) {
this.x = x;
}
}


The volatile keyword ensures that we will always get the in memory value of the integer x. This is lot cheaper than synchronizing the entire bean instance which might contain other values than just x. This is a good solution, a better but more constraining solution, is to make the bean immutable. This can only be done if you only intend to set the value of x once.



public class ThreadSafeBean {

private final int x;

public ThreadSafeBean(int x) {
this.x = x;
}

public int getX() {
return x;
}

}


The final keyword means that the value of this field once set cannot be changed. This also has repercussions for thread safety, because Java then also guarantees that the value will be seen by all threads without the need for any locking.

These few advices should help you implement thread safe classes. We looked both at the problems of state consistency and state visibility, and the language tools at our disposition to prevent them. Generally synchronize as little as possible, synchronization is not a big performance hitter anymore, but can still introduce problems with thread contention if you have many threads running. So instead try to use volatile when possible, and ideally make classes immutable. However, too much synchronization is still better than too little. Another important aspect is to document thread safety on your classes in the Javadoc, that goes for thread safe and unsafe classes. You documenting your class clearly signals to other developers what they can and can’t do with it, and as a lucky side effect might also make them ponder thread safety issues in their own code. If you are further interested in threading issues and solutions in Java, I recommend that you read Java Concurrency in Practice by Brian Goetz. It is an excellent book, well written and complete, about multithreading in Java.

Monday, August 6, 2007

Using AspectJ to detect violations of the Swing single thread rule.

As I pointed out in my previous entry, all swing components must be initialized and accessed through the Event Dispatch Thread (EDT) only. While a visual consequence of not doing so might never be observed, when they do they can have quite dramatic consequences for the user's confidence in your system. Therefore, some effort should be put into avoiding this problem by educating developers and providing a design that accommodates this constraint. However, experience tells that no matter how much effort you put into it up front, there will be a few glitches. Therefore, you may want to add new tool that can detect such defects during test, before you end up chipping your product out to the users. This is one instance where AspectJ becomes handy.

AspectJ is developed, as part of the eclipse project, to provide Java with a new extension to support aspect oriented programming. AspectJ is an interesting tool regardless of any knowledge or usage of aspect oriented programming. One of its most interesting capabilities is to inject new functionality into your binary code at runtime (as of Java 1.5), meaning that you do not to pollute your production code base with debugging functionality. The principle of AspectJ is fairly simple but allows for very powerful combinations, you write so called aspects, that define some functionality, an advice, that will be triggered when a predefined cutpoint is reached. A gross oversimplification, but somewhat helpful to get the idea, is to think of aspects as an advanced form of interceptors. In this entry, I'll show a very narrow application of this, to catch violations of the Swing single thread rule.

The aspect presented below contains two cutpoint definitions. The first called swingMethods() defines any call to a method on a class of the javax.swing package or on any class extending a class of the javax.swing package. The second cutpoint, safeMethods(), defines any call to a method called matching the expressions add*Listener or remove*Listener on a class of the javax.swing package or any class extending one. Also any call to setText() on a JComponent is included. What these methods have in common is that they are defined as thread safe by the swing framework. We have one advice defined, called checkCallingThread(), which logs a message to standard error as well as prints the stack trace. Using the @Before annotation with the two previously defined cutpoints, we define the advice to be executed before any call to a swing method except if it is part of the safe methods.

import java.awt.EventQueue;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;


@Aspect
public class EDTCheck {

@Pointcut("call (* javax.swing..*+.*(..)) || " +
"call (javax.swing..*+.new(..))")
public void swingMethods() {}

@Pointcut("call (* javax.swing..*+.add*Listener(..)) || " +
"call (* javax.swing..*+.remove*Listener(..)) || " +
"call (void javax.swing.JComponent+.setText(java.lang.String))")
public void safeMethods() {}

@Before("swingMethods() && !safeMethods()")
public void checkCallingThread(JoinPoint.StaticPart thisJoinPointStatic) {
if(!EventQueue.isDispatchThread()) {
System.out.println(
"Swing single thread rule violation: "
+ thisJoinPointStatic);
Thread.dumpStack();
}
}

}


The aspect is compiled like any other Java source file, and you and up with a regular class file. Now to running the aspect on some test code. The code presented below contains some legal calls to swing code and some illegal ones. The calls on the JLabel are illegal except for the addKeyListener() call. The calls to the JTextField are all legal because they take place on the EDT. All calls to the CustomJComponent are illegal. Now one last thing is needed to run our test, the aop.xml file to configure the aspectJ weaver.

package test;

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.event.KeyAdapter;
import javax.swing.JComponent;
import javax.swing.JLabel;

import javax.swing.JTextField;

public class Test {

public static void main(String[] args) {
JLabel jLabel = new JLabel();
jLabel.getText();

CustomJComponent customJComponent =
new CustomJComponent();
customJComponent.changeColor(Color.BLACK);

EventQueue.invokeLater(new Runnable() {
public void run() {
JTextField jTextField = new JTextField();
jTextField.getPreferredSize();
}
});

jLabel.addKeyListener(new KeyAdapter(){});
}

public static class CustomJComponent extends JComponent {
public void changeColor(Color color) {
}
}

}


The aop.xml presented below configures the aspectJ weaver to use our aspect to be weaved into any class in the test package. It is usually a good idea to restrict the weaving of aspects to the code set that you want to test, because weaving can slow things down significantly and there really isn't any point in weaving classes you know have nothing to do with Swing.

<aspectj>
<aspects>
<aspect name="EDTCheck"/>
</aspects>
<weaver options="-verbose">
<include within="test.*" />
</weaver>
</aspectj>


The aop.xml needs to be placed in a META-INF directory in your classpath. So to run this you simply execute the following command (assuming your classpath is set up correctly):

java -javaagent:c:/Temp/aspectj/lib/aspectjweaver.jar test.Test


The result looks something like this:

Swing single thread rule violation: call(javax.swing.JLabel())
java.lang.Exception
at EDTCheck.checkCallingThread(EDTCheck.java:26)
at test.Test.main(Test.java)
Swing single thread rule violation: call(String javax.swing.JLabel.getText())
java.lang.Exception
at EDTCheck.checkCallingThread(EDTCheck.java:26)
at test.Test.main(Test.java:15)
Swing single thread rule violation: call(test.Test.CustomJComponent())
java.lang.Exception
at EDTCheck.checkCallingThread(EDTCheck.java:26)
at test.Test.main(Test.java:16)
Swing single thread rule violation: call(void test.Test.CustomJComponent.changeColor(Color))
java.lang.Exception
at EDTCheck.checkCallingThread(EDTCheck.java:26)
at test.Test.main(Test.java:20)


We can see that all illegal calls have been captured and a useful stack trace points out precisely in the code where the problem occurs. This can be a good addition to your test toolkit, and can be used whenever the test team is running their tests, or by yourself when you have a suspicion of some threading problems in your Swing code. However, remember that this is not a static analysis tool and the code will actually have to be executed before any error can be detected. Therefore, if you do not thoroughly go through your entire UI during test, a lot of errors will go undetected.

This is only one of the many applications of AspectJ. I would recommend that you go visit the AspectJ website for more information and possible applications. This aspect can be successfully used as part of the development process for a Swing application to catch potential bugs as early as possible, which is the best time to catch them after all.

Sunday, August 5, 2007

Developing a Swing application: Why all the cursing?

If you’ve been around for enough time you have certainly heard your share of complaints about Swing, which usually from it is too complex, the UI is ugly, to it is too slow. Why all the cursing against Swing? Most certainly my few years of experience have taught me to be careful when coding with Swing components, and even more so during the design phase of my application. But is the Swing framework really to blame for all the failures? If you actually follow the rules and best practices as documented by its designers, will you end up with a fast, usable and appealing client? I believe you will and this has been proven by quite a few clients out there, some of the best examples can be found at the Swing sightings page. In this post, I will try and go through the main challenges, and give a few pointers to solutions, when writing Swing applications.

On modern hardware, you need to be able to run things in parallel in order to have access to the computational resources of your environment. You usually have multiple CPUs or Cores, and you want to be able to use all the available cycles available to you. In Java, this is mostly done using threads, and lots of them (Take a thread dump of any of your Java applications and you will see that even though you didn't create any, the JVM already has quite a few of its own). Creating a single threaded application is still possible but it should be restrained to simple applications (You don't want to bother with multi threading for implementing Tic-Tac-Toe). Java was one of the first languages to fully embrace threading as part of its specification. You can create multi threaded code that is both correct and portable, however, as all things code, it is only correct if you code it right, which can prove to be a challenge (Regardless of the Java language, code executed by multiple threads is hard to get right). So how does Swing propose to help with this? Well, by making all access to Swing components single threaded... Wait a minute! You just said that to create an efficient application you need to run things in parallel, with like multiple threads and stuff??? How does this help? Well, in fact it doesn’t and that is why you need to be extra careful when writing applications using the Swing framework.

Let’s just pause a moment and see why the single threaded model. Ideally, you would like to be able to just spawn of threads each time there is a new action taking place in your client. That should make use of all the available CPU time we can get, right? First, spawning off threads is not free, so you don't want to do it each time the user hits the keyboard or moves the mouse. Second, you're likely to chase bugs until the end of time itself and then for a little while longer. Each time a thread accesses a shared resource you need to synchronize access to it to make sure that the resource remains consistent through the multiple accesses. Now that you have synchronized the access to all shared resources (or more likely all the ones you know about) you've opened the door for deadlocks and still haven't fixed race conditions occurring because some threads need to synchronize access across several resources. So basically the wild wild west of threading is likely to see a lot of unlawful behaviour and not be that efficient at all because of all the time spent synchronizing. AWT, the predecessor to Swing and its foundation actually tried to deliver a framework allowing concurrent access through multiple threads. Let's just say that Sun's bug database regarding AWT is unlikely to be empty of threading issues anytime soon. Swing tried to fix that by introducing a simple, yet so hard to enforce, rule that all Swing components must be accessed by a single thread, namely the Event Dispatch Thread (EDT).


So how is this done? Well quite simply, each time you access some Swing resource (both reading or changing), you need to package it inside a new Runnable that you pass on to the EventQueue, just like this:

Runnable swingRunnable = new Runnable() {
public void run() {
// Doing some Swing stuff...
}
}
EventQueue.invokeLater(swingRunnable);


This plain sucks because, first these few lines of code will potentially be repeated over and over again in your code, this, however, in the minor annoyances category. Second, you only have one thread to execute all your code. This is a bit more critical; while the EDT is busy, clicking buttons and hitting the keyboard has no apparent effect, because your application cannot process these events until the current job on the EDT is done. This is a concern of perceived performance, most people don’t really mind looking at a progress bar (Actually, it can be quite fascinating), but looking at a frozen application will significantly increase their blood pressure. You don’t get things done faster with a progress bar, but the elapsed time somehow gets more acceptable. Thirdly, I sometimes forget to turn off the ironer, and while I might get away with it for my entire life, there's a chance that I will set my house ablaze some day. It is the same with Swing code, if you forget to put it on the EventQueue, it’s probably going to be okay, most of the time... However, some day you might receive a call from your customer at the hospital, asking why the application displayed the wrong amount of medication for that now deceased patient. Then, you’d wish your house went ablaze so you wouldn’t have had time to write that fatal line of code.

The first problem can be largely remedied be getting your design work right and structuring your code so that the Swing code is isolated from the rest of the code. If you end up having several invokeLater() calls inside a single method, it probably means you need to refactor your code. This might not always be possible with legacy code, in which case you might just have to live with it, you probably will have to live with worse things in your life as a code monkey.

The second problem is the single greatest cause of poorly performing Swing applications out there, some people have actually given up because of this, cursing the Swing framework for its slowness. So how do you fix this? Well several solutions exists more of less refined, but they all come from the same basic principle. You need to keep the amount of code executed on the EDT to a minimum and spawn as much processing as possible to other threads. Ideally, the code executed on the EDT only updates the state of the Swing components to reflect the results of the processing, not the processing in itself. If you do this, then your application would have a good perceived performance in most cases, and if you had some status reporting, like an hourglass or a progress bar, then you are almost certainly home safe. To help doing that several libraries and utility classes exist, the most famous is probably the SwingWorker, which is now part of the standard JDK since Java 1.6. This class allows you to easily split your code up into background processing code and Swing code. Other nice helper libraries include SPIN and the earlier Foxtrot. These two libraries decouple the actual data model from you Swing components. Looking forward you should pay attention to JSR 296, Swing Application Framework, which promises to include new concepts and utilities to ease threading concerns in Swing. So all is actually good in the fantastic world of Swing, well almost… The Swing framework actually has a few problems on its own, related to the infamous grey rectangle.

The grey rectangle problem is when some part of your application does not get repainted immediately and the region just shows up as a grey area, usually rectangular. This is actually caused by a deficiency in the design of Swing. Normally, the OS passes on events to applications for them to process the event and repaint part of their display if necessary. During that time, the OS is smart enough to realize that while processing the event, the application is not able to repaint itself should a new event force that, so the OS actually caches the current display of the application. Meaning that, even if you move another window on top of a busy application and move it away, the OS can use the cache to paint the busy application after the other window is moved away. The OS knows to use the cache because the application hasn’t returned from the last event that was passed to it. Swing on the other hand decouples the event processing from the OS, by placing the event on the EventQueue and returning control to the OS immediately. The OS has now no way to know that the application is still busy handling that event passed to it a while, and therefore does not use its cache to display the window. This problem is pretty much insolvable unless you change the fundamental design of Swing. A few things have been done to alleviate it over time, like in Java 1.6 with the introduction of double buffering on all components. All this means is that Swing repaints faster, meaning the grey rectangle is less likely to be noticeable. However, all these optimizations are not pointless, because if you actually keep the EDT mostly free, your application will plenty of time to repaint itself on a modern desktop.

The third problem is probably the most serious of all, because it is sneaky in its nature. It will remain hidden most of the time; you can successfully go through internal test, beta release, a few years of field test, until one day, it strikes in a place where you really did not want it to happen. Good design and implementation practices can help you avoid it to a certain extend, but even the best developers make mistakes (In fact, a good developer is often differentiated from a bad one, by the simple fact that he admits to making mistakes, and does something to catch them.) Static code analysis is unlikely to be able to detect this problem; this is in essence a runtime problem. Is my code running in the right thread? A few simple tricks, can allow you to detect violations to the rule. You can write a custom RepaintManager that will override the addDirtyRegion(), markCompletelyDirty() methods to check that these methods are being executed on the EDT. This can be simply done like this:

public class CustomRepaintManager extends RepaintManager {
public void addDirtyRegion() {
if(!EventQueue.isDispatchThread()) {
throw new RuntimeException(“Running on the wrong thread!”);
}
super.addDirtyRegion();
}
}


This will detect all accesses that would cause a repaint on the wrong thread. This, however, does not catch calls to Swing components that to not cause a repaint, which might lead to equally embarrassing bugs. An elegant solution to that is the use of aspects to do the detection. I will go more in depth with that solution and aspects in my next posting.

I hope this way too long posting has helped to give you a better understanding of the challenges involved in writing Swing applications and some pointers to a few solutions. In my opinion, if the development team keeps an eye on the few problems outlined here, developing Swing applications can give great results and be very cost efficient. Especially, if developing for several platforms, one of the main design goals of Swing is after all portability, which it has been largely successful.