Swing versus SWT Thread Confinement

Swing, SWT, and most (maybe all?) GUI APIs operate under some sort of thread confinement scheme. Most readers of this blog are probably somewhat familiar with the AWT/Swing event dispatch thread. Swing components are not thread-safe — they are thread-confined. This means when you call methods on Swing components, you must ensure you do so on the event dispatch thread. There are a handful of thread-safe exceptions to the rule, such as repaint().

During our last meeting it was brought to my attention that SWT adheres to a fail-fast policy. If you invoke SWT API methods from a foreign thread, an SWTException is thrown. Yes! This is the way to do it.

Swing, on the other hand, does not fail fast. Instead, if you execute Swing API methods outside the EDT, your app might work…or it might exhibit strange behaviour. You might notice painting artifacts, obscure exceptions, and possibly may encounter memory visibility issues on multi-processor systems.

Can We Fix Swing?

I suspect that most developers will agree a fail-fast approach works best. If your code has a bug, you may as well fail immediately with a specific exception (as SWT does), rather than live with subtle bugs (as Swing does) that are much harder to diagnose.

One approach involves changing every method in Swing as follows:

public void doSomething() {
  if (!SwingUtilities.isEventDispatchThread()) {
    throw new IllegalStateException(“…blah blah blah…”);
  }
  …normal code
}

Of course those three lines of code could be encapsulated into a helper-function of some sort, but the concept remains the same. This would require sweeping changes to Swing and is unlikely to happen. Throwing an exception, while arguably correct, does change the contract of these methods. Even if we do not like the current behavior, changing the semantics of nearly every Swing method may break quite a bit of code.

A More Serious Proposal

I believe annotations offer a more viable solution. Imagine if Java 7 Swing code added annotations to every Swing method that requires the EDT:

@RequiresEDT
public void doSomething() {
    …normal code
}

A new @RequiresEDT annotation would not change the behavior of any existing Swing API. It would, however, clearly document the intent of every Swing method. Furthermore, having that annotation in place (with runtime retention) makes it drop dead simple to use an AOP framework to enforce proper thread confinement. Or IDEs can more easily offer inspections that warn you of threading bugs.

Thoughts? Is this something we should pursue adding to Java 7?

5 Responses to “Swing versus SWT Thread Confinement”

  1. Peter Veentjer Says:

    Maybe you could have a look at the following page:

    http://weblogs.java.net/blog/alexfromsun/archive/2006/02/debugging_swing.html

    A similar solution based on AspectJ

  2. Marco Hunsicker Says:

    Do you know Scott Delap’s ThreadCheckingRepaintManager? Originally available through http://www.clientjava.com/blog/2004/08/31/1093972473000.html. Derived versions can be found in various FOSS projects. Related blog entry avaliable here: http://weblogs.java.net/blog/alexfromsun/archive/2006/02/debugging_swing.html

    The proposed annotation would sure be a good thing, but still require some additional effort to track down violations. Maybe in the future there will be Swing container frameworks available that provide easy to use threading support for Swing developers. It’s not that hard to get it right today, but every little help is a good thing!

  3. Vivek Prahlad Says:

    The simplest approach would actually be the ThreadCheckingRepaintManager that Marco’s mentioned – both the two other proposals are perhaps a bit too invasive. The spin
    project on sourceforge has a pretty nice implementation of a checking repaint manager – when violations are detected, it creates a filtered stacktrace that can help diagnose the exact cause of the problem.

  4. Curt Cox Says:

    EDT Annotation.

    Relevant thread:
    http://forums.java.net/jive/thread.jspa?messageID=139049&tstart=0

    Relevant JSR
    http://jcp.org/en/jsr/detail?id=305

    Discussion Group for JSR
    http://groups.google.com/group/jsr-305?hl=en

  5. M Easter Says:

    When I saw a concurrency presentation by Eric B, I had a thought that was somewhat similar to this. It was a personal light-bulb for me at the time. Let’s see if I can recapture the gist of it.

    Java 5 has powerful concurrency features, and certainly the “synchronized”/monitor pattern has been a big success as a language keyword. And yet there seems to be very little _in the language_ to help us distinguish a program that is thread-safe/correct from one that is reckless.

    Consider the basics of OO design: Java has many ways of conveying _intent_ when it comes to inheritence, polymorphism, generics, etc etc.

    Admittedly, OO design is probably vastly “easier” to describe syntactically than concurrency. _But_ what if we go beyond Swing and simply consider the problem of communicating the “threading intent” to another user and/or the compiler? (For example the contractual aspects of an interface from a concurrency standpoint. I’m thinking of copy-on-write/ownership/etc policies for objects).

    I hadn’t gotten there yet but almost certainly the answer, if there is one, lies in annotations. I think the Swing idea above is one example of what I had been trying to get at.

    My question: is there any academic research in this area? Are there any other languages that can act as a model? I remember long ago it seemed like everyone would mention Eiffel when it came to (a) design by contract and (b) exception handling (not sure on the latter). Which language is king of concurrency?

    Maybe Java is the leader in this space. There are a lot of threading problems in various Java/Swing programs but that is almost a testament to the success of the design. Poorly written multi-threaded programs in C/C++ won’t run long enough for people to complain about them.

Leave a Reply