Java多线程访问一个String

Ume*_*cha 0 java swing

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

String s = "When value is";
Run Code Online (Sandbox Code Playgroud)

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

例如,当textfield焦点更改时,字符串应为"当值为X"时,当组合更改时,字符串应为"当值小于X和Y"时

所以像上面四个线程将改变一个字符串.如果我不控制它们输出是意料之外的.解决这个问题的最佳方法是什么?我可以使用join()或者可以使用volatile但它会使代码变得复杂.

请分享您的想法.提前致谢.

Ben*_*Ben 6

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

如果你有四个不同的线程需要更新Swing组件,例如显示不同的String,他们应该通过将使用这些SwingUtilities方法在单个事件调度线程上运行的任务排队,invokeLater或者invokeAndWait例如

SwingUtilities.invokeLater(new Runnable() {
  public void run() {
    myComponent.setText("New string");
  }
};
Run Code Online (Sandbox Code Playgroud)

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

当然,如果现在看起来没有四个线程,只有四个事件处理程序在EDT上调用,那么这一点都不相关.