我有一个关于我一直在研究并寻找答案的事情的一般问题,现在已经 3 天了(并且出于纯粹的沮丧基本上放弃了。
场景 1;
A) 调用的方法创建并显示"请稍候.."JWindow component with .setVisible(true)
B)调用方法进行简单的计算和System.out的结果
C) "请稍候...."在步骤 B 执行期间按预期持续存在
D)步骤B终止,.setVisible(false)在"请稍候"窗口被调用,它按预期进行
目前为止,一切都好。
场景 2;
与场景 1 相同,只是步骤 B 中的工作要复杂得多,并调用一个自定义类,该类执行一堆数据库查询/写入,平均需要大约 3-6 秒才能完成。自定义类不可运行或线程化,只需调用;
customClass cc = new customClass();
cc.makeMyDataPlease();
- 无论出于何种原因,在场景 2 中,.setVisible(true) 步骤"A"直到复杂工作步骤"B"完成后才会发生。
我现在已经花了 2 1/2 天的时间尝试了本网站上发现的这些类型问题的许多解决方案,而其他解决方案则没有运气。尝试了 swingworker 、invokelater、thread等,得出的结论是,在撕掉更多的头发之前,我需要对此进行更多调查。
我在连接到 URL 并发布数据的方法时遇到了类似的问题。我试图在 Web 连接例程开始之前在一个简单的 JLabel 上设置文本,但它也失败了。文本是在 Web 例程完成后设置的。
就好像 VM 在线程化每个语句执行一样。
我怀疑 mysql 类和网络 URL 类共享属性(网络?),这些属性冻结了可能没有时间完成的其他任务。
这是我的问题/困惑:
如果主 java 线程中的执行是顺序的,除非创建/调用了新线程,为什么会干扰该 setVisible(true) 语句?从逻辑上讲,它必须在执行数据库例程语句之前完成,但它没有。
在java 中,确保一个语句在下一个语句之前完全执行的最终方法是什么?(或者至少,当下一个开始时,我相信 VM 可以足够快地执行 setVisible 操作,以至于它们甚至可以同步启动)。
提前致谢
具体来说,我的问题是:在处理Java中"阻塞"例程所涉及的并发问题时,最佳实践是什么,以及如何最好地在这些范围内工作。
与方案 1 相同,只是步骤 B 中的工作要复杂得多 并调用一个自定义类,该类执行一堆数据库查询/写入 平均需要大约 3-6 秒才能完成。自定义类是 不可运行或线程化,只需调用;
customClass cc = new customClass(); cc.makeMyDataPlease(); for 无论出于何种原因,在场景 2 中,.setVisible(true) 步骤"A"确实如此 直到复杂的工作步骤"B"完成后才会发生。
问题是,Swing是一个单线程环境。 与 UI 的所有交互都应在事件调度线程的上下文中执行。 任何阻止此线程的进程都将阻止它处理新事件,包括绘制请求。
发生的情况是,方案 2 很可能阻止了 EDT,阻止它显示窗口,但相反,当您完成所有处理时,EDT 会在打开事件后立即响应关闭事件。
由于框架的结构方式,您必须确保;
- 对 UI 的所有交互和修改都在 EDT 中完成
- 任何长时间运行或阻塞的进程都是在 EDT 之外完成的。
首先查看 Swing 中的并发性以获取更多详细信息。
在没有进一步证据的情况下,我的直觉是使用SwingWorker
例如。。。
import java.awt.EventQueue;
import java.util.concurrent.ExecutionException;
import javax.swing.JLabel;
import javax.swing.JWindow;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class QuickWorker {
public static void main(String[] args) {
new QuickWorker();
}
public QuickWorker() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JWindow window = new JWindow();
window.add(new JLabel("Look no hands!"));
window.pack();
window.setLocationRelativeTo(null);
}
});
}
public class Worker extends SwingWorker<Object, Object> {
private JWindow window;
public Worker(JWindow window) {
this.window = window;
}
@Override
protected Object doInBackground() throws Exception {
// Long running process...
Thread.sleep(5000);
return "All done";
}
@Override
protected void done() {
try {
// Get the results of the process if you want them...
get();
} catch (InterruptedException | ExecutionException ex) {
ex.printStackTrace();
}
window.dispose();
// This is only here because the example will keep running without it :P
System.exit(0);
}
}
}