Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 螺纹约束/摇臂_Java_Multithreading_Swing_Thread Safety_Swingworker - Fatal编程技术网

Java 螺纹约束/摇臂

Java 螺纹约束/摇臂,java,multithreading,swing,thread-safety,swingworker,Java,Multithreading,Swing,Thread Safety,Swingworker,我不清楚线程限制。 在swing中,必须通过EDT更新所有gui组件。SwingWorker在Java6中提供,用于长时间的操作,并且在done方法中可以更新gui组件。我的理解是,done()方法中的gui组件在EDT中更新。因此,应该没有同步问题。但是这里 它说: 因为ImageRetriever类将 下载图像并将其放置在 大标签,提供标签和 构造函数中的图像URL为 方便。ImageRetriever需要 检索图像的URL。提供 标签,使ImageRetriever 实例可以设置标签的图标

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

它说:

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

我对此感到困惑。如果SwingWorker方法更新EDT中的gui组件(在链接JLabel的示例中),为什么不在ImageRetriever(=SwingWorker)实例之间共享它们更安全?如果我们有多个SwingWorker,并且在done()方法中它们更新同一个组件,那么我们必须使用同步原语进行更新吗?我是不是误解了什么?线程限制不意味着只有一个线程将执行所有操作吗?荡秋千的人不受限制吗


谢谢

如果标签是在父类中声明的,并且由于某种原因,在某个时刻为该变量分配了一个新值,那么所有SwingWorker都将看到更新。因为这可能在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)

,但在您的示例中,标签由EDT之外的线程访问,这是不允许的。如果在您的示例中,缺少第二行(Thread1-label=new JLabel();),并且我们在EDT-label.setText(…)中有SW;EDT中的SW-label.setText(…);这是线程安全的。我的问题与Jtree有关,不像labelIt禁止在EDT之外的组件上调用方法那样简单,但允许分配变量。是的,如果没有对组件执行其他操作(没有线程1),那么它将是线程安全的。最后一个问题。如果我在SW的构造函数中传递jlabel,那么Thread1所做的任何更改都不会反映在SW done()方法中。对吗?我的意思是SW将引用一个标签,thread1将使标签指向另一个标签,但SW将使用旧值。如何确保在EDT中传递给构造函数的变量(如果更改)有新的值可供使用?如果,我有一个字符串变量,在调用SW.execute()之前它的值为“a”;调用execute后,变量的值为“B”,这在done()中如何可见?为什么允许赋值?我会认为这是非线程安全的?