9

I heard many times that Java Swing threading model is wrong. I don't fully understand why, I know that the problem is related to the fact that you can draw on a Drawable from another thread other than the main UI thread. I know that there are utility functionalities like SwingUtilities.invokeAndWait and SwingUtilities.invokeLater that let you do your painting in a Runnable, that in turn is run by the Event Dispatcher thread. I guess that this way you ensure that painting is done synchronously and this doesn't leave the buffer in an incosistent state.

My question is: how do "good" UI toolkits behave? What solutions are adopted?

gotch4
  • 13,093
  • 29
  • 107
  • 170
  • I'd like to know why downvote this question... what wrong with it? – gotch4 Nov 22 '12 at 20:43
  • 4
    Have an upvote. I think your question is fine. – Ravi Wallau Nov 22 '12 at 20:50
  • 2
    Maybe you could link a reference to where you heard that? – Axel Nov 22 '12 at 20:52
  • 5
    Do you have any references for this thesis? I've never heard it. Swing's threading model is utterly simple: it's called *single-threaded*. – Marko Topolnik Nov 22 '12 at 20:57
  • 5
    If you don't understand what you've 'heard', you can't expect people who haven't heard it to understand either. Maybe you should make more of an effort. Swing is single-threaded. So is Windows. So was OS/2 Presentation Manager. So is the X Window System. – user207421 Nov 22 '12 at 21:13
  • +1 for the request for reference –  Nov 22 '12 at 21:17
  • 2
    In the absence of an objective definition for "wrong" and lacking any specific complaint, let alone an example of a "good" threading model to compare it to, how is anyone supposed to write an objective answer to this question? Are we now in the habit of upvoting unanswerable questions? – meriton Nov 22 '12 at 21:30

4 Answers4

10

Brian Goetz's Java Concurrency in Practice,

9.1 Why are GUIs single-threaded?:

...In the old days, GUI applications were single-threaded and GUI events were processed from a “main event loop”. Modern GUI frameworks use a model that is only slightly different: they create a dedicated event dispatch thread (EDT) for handling GUI events. Single-threaded GUI frameworks are not unique to Java; Qt, NextStep, MacOS Cocoa, X Windows, and many others are also single-threaded. This is not for lack of trying; there have been many attempts to write multithreaded GUI frameworks, but because of persistent problems with race conditions and deadlock, they all eventually arrived at the single-threaded event queue model in which a dedicated thread fetches events off a queue and dispatches them to application-defined event handlers...

  • Another question might be, why, instead of invokeAndWait and invokeLater, not to use an approach that encloses the drawing calls in a pair of BEGIN_DRAW and END_DRAW methods, so that they take care of concurrency? I've seen this around, for example in OGL. – gotch4 Nov 22 '12 at 21:44
  • @gotch4 those methods actually incapsulates actions in `Runnable` and post them in the `EventQueue` so they become available to the `EventDispatchThread`. These actions are performed in EDT. When you use naive demarcation with methods you suggested -- everything that goes between them is performed in this current thread (not EDT). –  Nov 22 '12 at 22:04
3

For SWT: http://book.javanb.com/swt-the-standard-widget-toolkit/ch05lev1sec7.html

SWT implements a single-threaded user interface model that is typically called apartment threading. In this model, only the user interface thread can invoke user interface operations. This rule is strictly enforced. If you try to access an SWT object from outside the user interface thread, you will get an SWTException("Invalid thread access").

So SWT is single-threaded too. But it takes the extra step to forbid any changes to the UI outside of the UI thread. Consider the alternative in Swing where modifying the UI from somewhere else is allowed but will produce sooner or later unexpected results that will confuse the newbie programmer who will then learn that Swing is single-threaded the "hard" way.

Also, if your design is not clear, you may end up with situations where you think you are in the correct thread but in actuality you are not. You can also be unable to tell reliably what threads will access a specific piece of code, but then you probably have a serious design issue in you own code anyway.

Other than that, I can't imagine other reasons why Swing's threading model would be considered "wrong".

Cyrille Ka
  • 15,328
  • 5
  • 38
  • 58
  • How can SWT detect that another thread is messing up with the UI? Are all toolkit methods proxied and a check is done? – gotch4 Nov 22 '12 at 21:46
  • I am not sure since I'm not very experienced with SWT, but apparently not, since the stack trace of the error doesn't show a proxy and show the exception originates from methods whose names indicates they are checking something, like org.eclipse.swt.widgets.Display.checkDevice. Actually not all methods will throw an exception. Those who will are documented as susceptible of throwing SWTException with value ERROR_THREAD_INVALID_ACCESS. – Cyrille Ka Nov 22 '12 at 21:57
  • It can check this the same way as JavaFX does or as Swing does it if you use a custom RepaintManager as described in [this article](http://weblogs.java.net/blog/alexfromsun/archive/2006/02/debugging_swing.html) – Robin Nov 22 '12 at 21:59
1

The way current display technologies are implemented, painting pixels on a screen is always serial. You need to generate about 30 images a second, and paint them one by one.

So there is no need for this painting to be multi-threaded, because you would still have to do some synchronization in the background. And this is actually what Swing is doing - it uses a special thread called Event Dispatch Thread to schedule all changes to occur in time before the next image.

So technically, Swing is thread-safe, IF you use the EDT to submit changes. And that's what invokeLater() and invokeAndWait() methods are for. They submit changes to the EDT.

If you don't use EDT and submit some long-running change, such as computing some value after a button press, you can see the application become unresponsive, not repainting itself. Because the EDT is busy doing the calculation for you, and have no time to schedule repaints and other events.

Jakub Zaverka
  • 8,816
  • 3
  • 32
  • 48
0

Swing has a thread that is responsible for basically letting the user interact with the graphical portion of your application. If you only perform quick tasks in response to user initiated events, your application will always be responsive.

You might have an issue if you perform a long running task, from an user initiated event, without using a separated thread to run that task - the problem is that, while the task is running, the application will freeze. No repaints will occur, the user will not be able to interact with it all, it will look like the application just locked itself out.

If you are running a task in a separated thread (for example, you are downloading a page and you want to notify the user that the download has completed), then you can't update Swing directly from that task, instead you must use one of the helper methods you mentioned in your question.

It is a more labor-intensive process to create these tasks so that your application is always responsive - but if you are running something that takes a long time (downloading a file is a good example), the application will continue to be responsive even while the task is performed, and you can even let the user cancel the task, just as long as the task itself allows it. You can use a modal dialog to prevent the user from doing anything else while the task is performed (if you want to do so), or have a progress dialog that displays a spinning wheel or something like that. But I guess the important thing is not let the user think that the application just "froze" for no reason.

Ravi Wallau
  • 10,416
  • 2
  • 25
  • 34
  • Thanks for the answer, but this is the part that I knew more or less :) I'd like to know how the problem is tackled in other UI systems – gotch4 Nov 22 '12 at 20:59
  • @gotch4 They don't tackle it differently. They pretty much work like that all of them. – nos Nov 22 '12 at 21:16