线程限制/摇摆工人

发布于 2024-09-17 21:18:26 字数 854 浏览 3 评论 0原文

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

显示:

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

我对此感到困惑。如果 SwingWorker 方法在 EDT 中更新 gui 组件(在链接示例中为 JLabel),为什么不在 ImageRetriever(=SwingWorker) 实例之间共享它们会更线程安全?如果我们有多个 SwingWorker 并且在 did() 方法中它们更新同一个组件,我们必须使用同步原语进行更新吗?我是否误解了什么?线程限制不是意味着只有 1 个线程可以完成所有操作吗? Swingworkers不是有螺纹限制的吗?

谢谢

I am not clear about thread confinement.
In swing all the gui components must be updated through the EDT. SwingWorker is provided in Java6 for lengthy operations, and in the done method the gui components can be updated. My understanding was that the gui components in the done() method are updated in the EDT. Therefore there should be no synchronization problems. But here link text

it says:

Because the ImageRetriever class will
download an image and place it on a
large label, providing the label and
image URL in the constructor is
convenient. ImageRetriever needs the
URL to retrieve an image. Provide the
label so that the ImageRetriever
instance can set the label's icon
itself. If you use inner classes, you
might not even provide this
information in the constructor,
because the worker thread will be able
to access the information directly.
However, providing the information in
the constructor helps your application
to be more thread-safe because that
information will not be shared among
ImageRetriever instances

I am confused on this. If the SwingWorker methods update the gui components (in the example of the link the JLabel) in the EDT, why is it more thread-safe to not share them among ImageRetriever(=SwingWorker) instances? If we have multiple SwingWorkers and in the done() method they update the same component, we must use synchronization primitives for the update? Am I missunderstanding something? Doesn't thread-confinement mean that only 1 thread will do all the actions? Aren't swingworkers thread-confined?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

活雷疯 2024-09-24 21:18:26

如果标签在父类中声明,并且由于某种原因在某个时刻为该变量分配了新值,则所有 swingworkers 都会看到更新。因为这可能在 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(...);
} 

如果变量被定义为软件的属性,您将必须创建某种方法来获取存储在主类中的值(例如,吸气剂)

If the label is declared in the parent class and for some reason a new value is assigned to that variable at some point, then all the swingworkers will see the update. Because this might happen while the EDT is updating things, it can lead to weird behaviors.

For instance:

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

If the label variable is shared you will get an inconsistent state (label without text or icon).

Update
Storing the label as a variable passed through the constructors is a way to avoid this issue. If you want to see changes but not in the middle of a method execution, on way is to use a method local variable. You assign it at the beginning of the method to make sure it's not going to be changed outside.

If you use inner classes and the attribute of the parent class this will look like this:

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

If the variable is defined as an attribute of the SW, you will have to create some way of getting the value stored in the main class (eg. a getter)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文