【发布时间】:2014-11-02 00:00:08
【问题描述】:
我很难让我的一些代码正常工作。代码以SwingWorker 开头并获取结果。我无法将数据传递给工作人员并从工作人员那里获取信息。
我要传递的数据由我自己定义的类的对象组成。例如,我有一个 Item 和 Inventory 对象。 Item 对象基本上包含所有原始类型(名称、价格等),Inventory 包含 LinkedList 的 Items。
我不太记得导致我的健全性检查的一系列事件,但作为健全性检查,我实现了Item.getDeepCopy(Item inItem) 和Inventory.getDeepCopy(Inventory) 函数,以便我可以传递Items 和@987654331 的副本@s 给我的工人。 这需要吗?
当我将数据传递到我的StringWorkers 并从中获取数据时,我如何使用深层复制功能。假设我通过单击按钮启动了一个工作人员。在事件处理程序中,我首先获得了Inventory 或Item 的类私有本地副本的深层副本,并将其传递给worker 构造函数。 这是正确的吗?我需要传递一个深拷贝吗?我认为不需要..
我这样做是因为担心 worker 会尝试修改对 worker 内部对象的类引用,从而导致一些线程问题。但是经过一些阅读和批判性思考后,情况并非如此,因为 java 是按值传递的,所以传递给 worker 的内容不可能导致 GUI 组件数据发生变化。 这是正确的想法吗?
然后,当工作人员完成时,它会调用我编写的重写 done 方法。此方法在 EDT 上运行,因此我可以从我的 GUI 组件调用函数,即我调用的函数WorkerDone(boolean result, Inventory outInv)。工作人员调用此函数并将其本地副本 Inventory 或 Item 传递(不是深层副本)回 GUI。当 GUI 获取它时,它会执行深层复制并将其本地 Inventory 或 Item 设置为此值。 这对深拷贝有用吗?
编辑:更多。
基本上,我想将“一些数据”传递给工作人员,并允许它在不链接到 GUI 组件的情况下对其进行处理。当工作人员完成时,它要么成功完成,要么不成功。如果成功,我想从工作人员那里“取回”数据,并用返回的数据更新我的本地副本。我不希望工作人员“触摸” GUI 中的任何数据。
对于可变性。我希望能够在创建对象后更改对象中的数据。考虑到这一点,这就是我构建应用程序的方式。我想要的不是非可变对象来保证线程安全,我只是不希望线程交互。我想向工作人员传递一些数据,基本上“忘记我发送了它”,然后当工作人员完成并调用 GUI 的 workerDone 方法时,GUI 只是同意将其数据的本地副本设置为如果工作人员说它成功,则返回对象。
编辑 2:
只是为了更清楚地理解传递值和传递引用这两个短语。当我看到按值传递时我的想法。假设我想按价值传递一个苹果,为此我会将我的苹果放在一台克隆机中,该机器在各个方面都对苹果进行完全相同的克隆,然后传递那个苹果。不管是谁通过了这个克隆的苹果,它都可以用它做任何事情,并且不会影响我最初的苹果。
当我看到 pass-by-reference 时,我的想法是,如果我想通过引用传递我的申请,我会在一张纸上写下我的苹果在哪里,然后通过它。任何收到这张纸的人都可以到我的苹果所在的地方咬一口。
所以我的困惑来自“Java 是按值传递”,如果是,那我为什么要担心我的工作人员在对传递给它的值进行操作时会导致线程冲突?
【问题讨论】:
-
由于您没有说明需求的具体细节,因此不确定这是否是一个很好的例子。如果您想在后台更新
Items 和Inventorys 的状态,并且这些更改应该对用户可见,直到后台工作完成,那么只需传递您当前的对象。如果您想更新状态,但用户仍然应该看到更新前的值,那么这是深度克隆的一个很好的例子。 -
SwingWorker 的重点是确保对 GUI 的安全修改。您似乎关心不一定与 GUI 相关的元素(未直接显示在屏幕上),或者?
-
我做了一个编辑,试图让交互的细节更清晰,如果你能评论和回复,对我会更有帮助!
-
嗨 - 你的比喻很好。在这种情况下,“按值传递”意味着 1) 你有一个苹果,2) JVM 给了你一张苹果所在的纸(一个“参考”),3) 当你传递苹果时,你 传递那张纸的副本。问:这有帮助吗?
-
在 java 中有没有办法取消引用指针并将其末尾的数据传递给函数?或者这就是我写深拷贝的原因?
标签: java multithreading user-interface swingworker