Daniel Pitts’ Tech Blog

Archive for February, 2008

Swing Concurrency

Saturday, February 9th, 2008

So many Java programmers get loured into the Swing trap. I’m not saying Swing is bad, but it has some pitfalls that many programmers fall into simply because they weren’t told otherwise.

The biggest pitfall is that most Swing classes are not thread safe, and there is a specific approach you must take to communicate with these classes.

Where there are many ways to approach thread-safety, the designers of Swing choose the “thread-partition” approach. What this means in simple terms is that any time you want to access data or methods in a Swing class, you should do it on a specific thread. This is much easier done than said.

Normally when you access an object, you use “ob.member”, for example: textField.setText("foo"). In Swing, you need to make sure your code gets called only from the Event Dispatch Thread (that’s the “single thread” as designated by Swing).

Communicating from any thread to Swing

In order to get your code to run on that thread, you can pass a Runnable to the java.awt.EventQueue. If you don’t know, Runnable is an interface in the standard Java API that has one method, public void run(); For example, in the above “foo” example, I could do this:

public void setFoo() {
   Runnable setFooRunnable = new Runnable() {
     public void run() {
       textField.setText("foo");
     }
  }
  EventQueue.invokeLater(setFooRunnable);
}

EventQueue.invokeLater tells the Event Dispatch Thread (EDT) to execute that code at its earliest convenience. invokeLater returns immediately, which may have consequences if you expect things to be done. There is another method that lets you wait until the EDT has completed your task, but it is strongly discouraged to use it.

There was a time in the past when Sun suggested that you could initialize your GUI outside of the EDT. They were wrong. Yes, I said it. Sun made a mistake. They have since sent out a correction, but unfortunately the harm was done and you’ll see some tutorials exemplifying this dangerous practice. If you so as much create an instance of a GUI object, do so on the EDT under bane of glitch. It may appear to work, but it will crash sometime, somewhere, and you might not ever hear about it from the customer who decided not to buy.

Don’t block the EDT, ever!

There is another consequence of this single thread approach. If you do something that takes a long time, and you do it on the EDT, you’ll make the whole application unresponsive. Most GUI’s, Swing included, are Event Driven, so instead of waiting for something, you should listen for that something. Most Swing components allow you to add listeners to them. The methods on your listeners get called when something they care about happens. This lets you avoid things like “while (!isFooRead()); doSomethingWithFoo(getFoo());” and instead you have “public void fooIsReady(Foo foo) { doSomethingWithFoo(foo); }“.

EDT is lazy, don’t give it hard work!

For the same reason you shouldn’t block the EDT, you should move time-consuming tasks (IO, calculations, etc…) off of the EDT. Every millisecond you take on the EDT is another millisecond that a mouse-click doesn’t get registered, or the window doesn’t repaint. This will give your program the appearance of being slow and unresponsive.

Java 1.6 has added a new class called SwingWorker that helps you pass work between a worker thread and the EDT in a clean and “correct” manor.

Where to go from here

Hopefully at this point you’ve learned the basics of what it takes to write a proper Swing program. From here, I suggest reading Concurrency in Swing from the Java tutorials. For a much more complete understanding of the why’s and how’s of Java concurrency, I suggest buying and reading Java Concurrency in Practice.

Assembly line: Separation of concerns with Inversion of Control.

Friday, February 1st, 2008

If you decide to go the route of using Inversion of Control and Dependency Injection, it can make your program a lot more flexible. If you do this manually, you’ll find that even a complex system can be managed well this way.

A common idiom is to use Dependency Injection to separate the creation of the object from the use of the object. The client object has some way to receive other objects it needs to “talk” to, but the client object doesn’t care how they were created:

class MyClient {
   MyFooService fooService;
   MyBarService barService;
   public MyClient(MyFooService fooService, MyBarService barService) {
      this.fooService = fooService;
      this.barService = barService;
   }

   public void doStuff() {
      fooService.iLikeFooFighters();
      barService.buyRoundsForEveryone();
   }
}

From this code snippet, FooService and BarService could be interfaces, abstract classes, or even concrete classes. If you change your mind later about them, MyClient doesn’t have to change at all

Another common approach for DI is to use setter based injection. This approach is useful for complex object graphs that have cyclic dependencies. I’ll leave it as an exercise for the reader to re-write MyClient with setters.

So, in this phase one, you’ve separated the concern of object creation and wiring from object usage. It is perfectly acceptable to stop here. However, depending on how complicated your object system is, you may wish to separate the concerns even further. You can do this via the Builder pattern (nb. The current Wikipedia entry on Builder pattern is incorrect and misleading.)

With the builder pattern, you separate the concern of creation from the concern of “wiring”. The builder accepts a series of objects that belong in a graph. The builder knows how to connect the objects through DI, but doesn’t care where the objects came from or how they were created/configured.

In a recent project of mine, I had to create a Robot instance, and wire it with a lot of components. To make things worse, some of the components also needed sub-components, and some components needed to know about other components, and some needed to know about the robot itself. I had successfully created a class that would create the components and wire them together, but it was a bit fragile (do things in the wrong order and you get an NPE, since not all of the components were created yet).

To solve this design issue, I created a class (HardwareContext), which held a reference to every component that it takes to build a robot. Those fields were populated using setter based dependency injection. Once those references are all created, hardwareContext.wireRobot() is called, and that is where all of the object graph is connected. This would allow me to create a new hardware context that wired the components differently if I needed to. It also allows me to create a new HardwareSpecification (the class that creates components), which creates different configurations for the robot.

This leads to a highly extensible and configurable system. It also makes it easy to figure out where to add a line of code. If the line is doing wiring, it goes into the Context, if it is creating an object, it belongs in the Spec. Easy, clean, clear.