Java Swing EDT&并发 [英] Java Swing EDT & Concurrency

查看:155
本文介绍了Java Swing EDT&并发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是想知道是否仍然有必要确保invokeLater()Runnable的同步性。

I was just wondering if it is still necessary to ensure synchronicity in an invokeLater() Runnable.

我遇到死锁,需要克服它,同时保持并发。

I am encountering deadlock and need to overcome it while maintaining concurrency.

这是一个好的代码示例吗?:

Would this be an example of good code?:

private String text;

private void updateText()
{
    SwingUtilities.invokeLater(new Runnable()
    {
        public void run()
        {
            synchronized(FrameImpl.this)
            {
                someLabel.setText(text);
            }
        }
    });
}

很抱歉的例子很不好,但我们必须假设 text 正在被不同的线程修改,无法注入,并且依赖于正确的值。

Sorry for the rather bad example, but we must assume that text is being modified by different threads, cannot be injected, and is reliant on a correct value.

我将无意中通过将同步代码发送到未知上下文中来创建一个死锁问题。?

Is this the proper solution or will I unintentionally create a deadlock problem by sending synchronized code off into an unknown context..?

谢谢。

推荐答案

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

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).

这篇关于Java Swing EDT&并发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆