且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Java Swing EDT&并发

更新时间:2023-01-13 18:02:05

更好的解决方案是这样的:

A better solution would be something like this:

public class Whatever {
    private String text;
    private final Object TEXT_LOCK = new Object();

    public void setText(final String newText) {
        synchronized (TEXT_LOCK) {
            text = newText;
        }
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                someLabel.setText(newText);
            }
        });
    }

    public String getText() {
        synchronized (TEXT_LOCK) {
            return text;
        }
    }
}

线程尝试同时调用 setText ,那么它们不会相互破坏。第一个线程将设置 text 的值,并使用该值入列一个UI更新。第二个线程也会设置 text 的值,并添加第二个UI更新。

This will ensure that if two threads try to call setText concurrently then they will not clobber each other. The first thread in will set the value of text and enqueue a UI update with that value. The second thread will also set the value of text and enqueue a second UI update.

最终结果是UI将最终显示最近的文本值,但内部 text 变量将立即 包含最近的值。

The end result is that the UI will eventually show the most recent text value, but the internal text variable will immediately contain the most recent value.

有几个注释:


  1. 使用单独的锁对象(即 TEXT_LOCK )意味着你不容易在其他地方锁定监视器上的任何实例和无意中导致死锁。***总是保持严格控制你的锁对象。

  2. 您可以制作整个 setText 方法

  3. 读取 text 的值也需要即使 Strings 是不可变的,也是同步的。 Java内存模型有一些细微之处,这意味着总是需要对可以由多个线程读取/写入的变量进行同步。

  1. Using a seperate lock object (i.e. TEXT_LOCK) means you are not vulnerable to code somewhere else locking the monitor on the Whatever instance and inadvertently causing a deadlock. Best to always keep tight control of your lock objects. It's also best to minimize the size of your synchronized blocks.
  2. You could make the whole setText method synchronized, subject to the caveat that it does make you potentially vulnerable to deadlock as above.
  3. Reading the value of text also needs to be synchronized even though Strings are immutable. There are subtleties to the Java memory model that mean you always need to synchronize around variables that can be read/written by multiple threads.

查看Brian Goetz的 Java并发实践,深入了解一些棘手的部分并发(包括内存模型奇怪)。

Check out Brian Goetz's Java Concurrency in Practice for a great dive into the tricky parts of concurrency (including the memory model weirdness).