Java threading introduction  Thread-safety  Thread methods  Interruption  Thread scheduling  Context switching  Thread priorities  sleep()  yield()  Deadlock  Threading with Swing  invokeLater()  Thread pools  CoundDownLatch  ThreadPoolExecutor  CyclicBarrier

Threads Database Profiling Regular expressions Random numbers Compression Exceptions C Equivalents in Java

Threading with Swing

You may have written a GUI-enabled application using a framework such as Swing, and never even given a thought to threads. And for some types of application, you pretty much don't have to. If everything in your application happens directly in response to a button click or other Swing event, and your application never "does things with threads" (it never sleeps, spawns another thread or process, "does something in the background" etc), then be it by good design or good fortune, it may be behaving correctly. But there are times, particularly if your application does want to "do something with threads", when you need to understand how threading works with respect to the GUI system.

As you'll know if you've programmed with GUI systems such as Swing, everything generally happens in response to events. You define an event handler, which is effectively the code you would like to be called when something happens. For example, we can define a button like this:

JButton b = new JButton("Click me");
b.addActionListener(new ActionListener() {
  public void actionPerformed(ActionEvent e) {
    // Code will be performed when button clicked
  }
});

To our program, the call to our method just "comes out of nowhere". But in reality, it must come from somewhere. That is: there must be some particular thread that's calling into our method. Well, there is, and it's quite a well-defined thread.

The event dispatch thread

The thread making calls to our event handlers is the event dispatch thread. This is a special thread that the GUI system sets up for performing UI tasks. Essentially, all user interface code will be executed by this special thread. Having a single designated thread handling the entire UI avoids a lot of issues that would occur if we tried to allow, say, different event handlers to be called by arbitrary threads.

In most Swing applications, if you've not thought about it and done anything special to use other threads, then practically all of your application will probably happen in the event dispatch thread. What you might not have thought about is whether it's all happening correctly...

Proper threading behaviour of GUI applications

There are essentially two rules of thumb that you need to remember:

  • always manipulate your user interface from the event dispatch thread (with one or two safe exceptions);
  • never block or delay the event dispatch thread— in other words, never call methods such as Thread.sleep(), Object.wait(), Condition.await() inside an event handler.

In more detail, these two guidelines have a few implications:

  • all tasks that we perform inside an event handler should be instantaneous; we should not perform a long-running task (such as making a database query) or call Thread.sleep() or Object.wait() or similar calls directly from an event handler;
  • to perform such long-running tasks, we need to arrnage for them to happen in another thread, e.g. by starting a new thread specially for the task;
  • we need to be wary of the more "subtle" library calls that might cause our thread to wait: if we use one of the concurrency utilities such as a ThreadPoolExecutor, we need to make sure we use a variant that won't ever block waiting for room in the queue; other slightly more obvious no-nos are awaiting a latch, joining another thread, calling Future.get()... essentially anything that "waits" for something cannot be called inside an event handler;
  • if we're in our other thread and need to update the UI (e.g. to report progress to the user), we generally need to arrange for that update code— and only the update code— to happen in the event dispatch thread;
  • by "manipulating the UI", we mean calling methods on or changing the state of any Swing components but also modifying any objects they depend on such as table models, cell renderers etc; firing events must also happen in the event dispatch thread.

How do you make something happen in the event dispatch thread?

So far, we've glibly said that in certain cases we must run something on the event dispatch thread. But how do we actually do that? On the next page, we look at the special method SwingUtilities.invokeLater() which provides us with this functionality.

comments powered by Disqus

 Java threading articles  Java threading and concurrency  Java profiling  Java performance graph index

Unless otherwise stated, the Java programming articles and tutorials on this site are written by Neil Coffey. Suggestions are always welcome if you wish to suggest topics for Java tutorials or programming articles, or if you simply have a programming question that you would like to see answered on this site. Most topics will be considered. But in particular, the site aims to provide tutorials and information on topics that aren't well covered elsewhere, or on Java performance information that is poorly described or understood. Suggestions may be made via the Javamex blog (see the site's front page for details).
Copyright © Javamex UK 2013. All rights reserved.