螺纹禁闭/ swingworkers

时间:2010-09-04 20:00:55

标签: java multithreading swing thread-safety swingworker

我不清楚线程限制。 在挥杆过程中,必须通过EDT更新所有gui组件。 SwingWorker在Java6中提供用于冗长的操作,并且在done方法中可以更新gui组件。我的理解是,在EDT中更新了done()方法中的gui组件。因此应该没有同步问题。但是link text

它说:

  

因为ImageRetriever类会   下载图像并将其放在   大标签,提供标签和   构造函数中的图像URL是   方便。 ImageRetriever需要   用于检索图像的URL。提供   标签使ImageRetriever   实例可以设置标签的图标   本身。如果您使用内部类,那么   可能甚至没有提供这个   构造函数中的信息,   因为工作线程能够   直接访问信息。   但是,提供信息   构造函数可以帮助您的应用程序   因此更加线程安全   信息不会在其中分享   ImageRetriever实例

我对此感到困惑。如果SwingWorker方法更新了EDT中的gui组件(在JLabel链接的示例中),为什么不在ImageRetriever(= SwingWorker)实例之间共享它们更加线程安全?如果我们有多个SwingWorkers并且在done()方法中他们更新了相同的组件,我们必须使用同步原语进行更新?我想念一些东西吗?线程限制是否意味着只有一个线程会执行所有操作?不是摇摆工作者线程限制吗?

由于

1 个答案:

答案 0 :(得分:1)

如果标签是在父类中声明的,并且由于某种原因在某个时刻为该变量分配了一个新值,那么所有的swingwkers都会看到更新。因为这可能发生在EDT更新事物时,它可能导致奇怪的行为。

例如:

SW in EDT - label.setText(...);
Thread1 - label = new JLabel();
SW in EDT - label.setIcon(...);

如果共享标签变量,您将获得不一致的状态(没有文字或图标的标签)。

<强>更新 将标签存储为通过构造函数传递的变量是避免此问题的一种方法。如果要查看更改但不想在方法执行过程中使用,那么就是使用方法局部变量。您可以在方法的开头指定它,以确保它不会在外部更改。

如果使用内部类和父类的属性,它将如下所示:

public void done() {
  JLabel l = label;
  l.setText(...);
  l.setIcon(...);
} 

如果变量被定义为SW的属性,则必须创建一些获取存储在主类中的值的方法(例如,getter)