-1

I've read that AWT upon which Swing is based, runs in a single event dispatch thread, and thus most of the API is intentionally not thread-safe. For long running operations use of SwingWorkers is recommended.

But how SwingWorker achieves thread-safety under the hood? How is it possible that my line of code button.setText("updated") ran from SwingWorker's separate thread is thread-safe, while from an ordinary thread it wouldn't be?

kebabdubaj
  • 35
  • 2
  • *"How is it possible that my line of code button.setText("updated") ran from SwingWorker's separate thread is thread-safe, while from an ordinary thread it wouldn't be?"* -- that is simply not true. Code called from a background thread of any type, be it a plain vanilla background thread or a SwingWorker's doInBackground method, should not contain code that calls Swing directly (with a few exceptions). – Hovercraft Full Of Eels May 22 '22 at 03:03
  • The difference between the two is that a SwingWorker has structures that allow you to direct some calls to be queued onto the Swing event thread, the `done()` method and the `process(...)` methods, for example. – Hovercraft Full Of Eels May 22 '22 at 03:03
  • @HovercraftFullOfEels in this short article by O'Reilly: https://www.oreilly.com/library/view/learning-java-4th/9781449372477/ch16s05.html, `JButton` is accessed directly in `doInBackground` of `MysteryWorker` class – kebabdubaj May 22 '22 at 03:10
  • They shouldn't be doing that. The `solveButton.setEnabled(true)` should be called in the `done()` method or in a PropertyChangeListener triggered by the worker. – Hovercraft Full Of Eels May 22 '22 at 03:16
  • @HovercraftFullOfEels I believe even the whole point of this article is that when you need to access Swing components from a long running thread `SwingWorker` is just made for that – kebabdubaj May 22 '22 at 03:20
  • I mean that's how I interpret what the author's mean to say and thus, it's hard for me to believe that it is a simple mistake made by them – kebabdubaj May 22 '22 at 03:21
  • Again, that code is wrong. There is no magic directly from within a SwingWorker's doInBackground method, but again, it does have mechanisms that allow for Swing thread-safe calls, but not as it is illustrating things. – Hovercraft Full Of Eels May 22 '22 at 03:21
  • Better that you get your information from the source: [Lesson: Concurrency in Swing](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/). I urge you to read this article critically as it will go into the details of exactly what you're asking. – Hovercraft Full Of Eels May 22 '22 at 03:23
  • @HovercraftFullOfEels okay so let's consider a scenario from my friend's university, he is required to print a timestamp each 500 ms in a `JTextArea`. He also has to make a `JButton` that let's you suspend and resume the printing of the timestamp and it is explicitly stated that he must use `notify()` and `wait()` to achieve that – kebabdubaj May 22 '22 at 03:23
  • @HovercraftFullOfEels ok I will dig into that article as well thanks – kebabdubaj May 22 '22 at 03:24
  • That project can be done, but I would take care to queue up the `JTextArea#append(...)` method calls onto the Swing event thread using `SwingUtilities.invokeLater(() -> { textArea.append("foo"); });` so that even if it is called from a background thread, it is called on the EDT (as per the article that I linked to). – Hovercraft Full Of Eels May 22 '22 at 03:30
  • @HovercraftFullOfEels straight facts, thanks, case closed for me – kebabdubaj May 22 '22 at 03:33
  • 2c from me. I have checked pretty much all the books that mention Swing. I dont remember any book to get right the threading issues that appear in Swing. Only oracle documentation is trustful. This specific book I haven't see it, but being wrong might be the case. Yes, books get some things wrong sometimes. :) – George Z. May 24 '22 at 08:18
  • if you want to do EDT updates from doInBackground of a worker, a simple solution is to call SwingUtils.invokeAndWait(()->dostuff(););. It will slow the thread a bit, but the dostuff() will be called in EDT – George Z. May 24 '22 at 08:19

0 Answers0