繁体   English   中英

Java 多线程访问一个String

[英]Java multiple threads accessing one String

我有一个字符串,将由四个不同的线程以不可预测的顺序访问。

String s = "When value is";

现在上面的字符串 s 将由四个不同的线程通过 Java Swing EDT 更新。 我有两个 JCombobox 和两个 JTextField。 这些组件的内部事件处理程序我将不得不更新上面的字符串。

例如,当文本字段焦点更改时,字符串应为“当值为 X”时,当组合更改时,字符串应为“当值小于 X 和 Y”时

所以像上面的四个线程将改变一个字符串。 如果我不控制它们 output 是出乎意料的。 解决此问题的最佳方法是什么。 我可以使用 join() 或 go 来表示 volatile,但它会使代码变得复杂。

请分享你的想法。 提前致谢。

首先, String是不可变的,因此无法更新。 然而,另一个 object(例如 Swing 组件)可能持有对String的引用,并且可以更新此引用以指向不同的String 这是在 GUI 中更新文本时通常会发生的情况。

如果您有四个不同的线程需要更新 Swing 组件,例如显示不同的String ,他们应该通过使用SwingUtilities方法invokeLaterinvokeAndWait将要在单个事件调度线程上运行的任务排队来完成,例如

SwingUtilities.invokeLater(new Runnable() {
  public void run() {
    myComponent.setText("New string");
  }
};

或者在更复杂的应用程序中,您可能希望从这四个线程中的每一个更新域 object,然后需要是线程安全的,然后分别更新 EDT 上的 Swing 组件。 在我看来,创建线程安全的代码并不容易。 我强烈推荐这本书Java Concurrency in Practice ,但重点是确保一次只有一个线程执行任何涉及 object 暂时处于不一致 Z9ED39E2EA931586B73A985A6942 中的操作。 这有时可以通过适当使用现有的线程安全类和原子操作来实现,但可能需要使用锁,通常通过synchronized方法或块。

当然,如果像现在看来,您根本没有四个线程,而只有四个在 EDT 上调用的事件处理程序,那么这些都无关紧要。

正如评论中提到的,只有一个事件调度线程。 除非您不正确地使用 Swing (并且Ben的回答说明了这一点),否则您真正的问题是您不知道触发事件的顺序。

即使对于单个组件,也无法控制此顺序。 尝试使用join或某种形式的锁定机制只会挂起您的应用程序。

解决方案是创建一个 object 在输入源之间进行调解。 根据您的描述,这可能是一个简单的Map<String,String> ,其中键是事件源,值是您最终想要显示的任何内容。

您的动作侦听器每个都向此 map 添加一个值,当添加第 4 个值时,您决定应将哪个值写入 output。

然后清除 map,等待下一组输入。

您应该假设处理事件的顺序是正确的顺序来编写程序。

让我们假设一下,您希望同一字段有多个事件,并且顺序非常重要。 但是,您不相信 EDT 会按照您需要的顺序通知事件。 您能否举例说明订单不正确的地方以及您打算如何更正它?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM