Tom*_*tin 9 java swing thread-safety
JOptionPane.showMessageDialog应该是一个有用的实用程序,用于获取用户反馈,因为它会在您等待时阻止当前线程.
因此我希望它是线程安全的,你不需要在invokeLater或invokeAndWait中包装调用.
是这样的吗?
取自javax.swing包描述:
Swing的线程策略
一般来说,Swing不是线程安全的.除非另有说明,否则必须在事件派发线程上访问所有Swing组件和相关类.典型的Swing应用程序响应于从用户手势生成的事件进行处理.例如,单击JButton会通知添加到JButton的所有ActionListener.由于在事件调度线程上调度了从用户手势生成的所有事件,因此大多数开发人员不受限制的影响.
然而,影响在于构建和显示Swing应用程序.不会在事件派发线程上调用对应用程序的主方法或Applet中的方法的调用.因此,在构造和显示应用程序或applet时,必须注意将控制转移到事件调度线程.传递控制并开始使用Swing的首选方法是使用invokeLater.invokeLater方法调度要在事件派发线程上处理的Runnable.
JOptionPane没有记录它是线程安全的,所以你必须使用invokeLater().
您应该只从事件调度线程调用此方法,因为这是应该与Swing组件交互的唯一线程.
如果您希望在等待用户反馈的同时暂停后台处理,我建议您使用SwingWorker实现,该doInBackground()方法定期调用publish(),允许process()在Swing线程上调用. doInBackground()然后可以阻止,直到采取一些行动process().例如:
new SwingWorker<Void, Void>() {
private volatile boolean done;
// Called on background thread
public void doInBackground() {
for (int i=0; i<1000000; ++i) {
// Do work
if (i % 1000 == 0) {
publish(); // Will cause process() to be called on Event Dispatch thread.
synchronized(this) {
wait();
}
if (done) {
System.err.println("Background thread stopping.");
return null;
}
}
}
}
// Called on Event dispatch thread.
protected void process(List<Void> chunks) {
if (JOptionPane.showConfirmDialog(getFrame(),
"Do you want to quit?", "Confirm Quit",
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) {
done = true;
}
synchronized(this) {
notifyAll();
}
}
}.execute();
Run Code Online (Sandbox Code Playgroud)