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?