0

我已经引用了这个先前的问题以及其他来源,但无法让 CountDownLatch 正常工作。

背景:mainFrame 创建名为 dataEntryFrame 的新 Frame。当点击dataEntryFrame“提交”按钮时,记录添加到数据库和dataEntryFrame被处理。此时,mainFrame 应该清除并重新加载一个显示所有记录的 jList。

问题:加载 dataEntryFrame 时,java 冻结,dataEntryFrame 组件永远不会加载。我无法通过这部分......然后,在 DataEntryFrame 中,CountDownLatch 应该只在单击提交按钮后递减,成功地将记录添加到数据库表中,然后自行处理。或者当用户点击取消...

代码:来自 MainFrame

clearList();
CountDownLatch dataEntryDone = new CountDownLatch(1);
DataEntryFrame f = new DataEntryFrame(dataEntryDone);
Thread newThread = new Thread(f);
newThread.start();
dataEntryDone.await();
reLoadList();

代码:来自 DataEntryFrame

public void run(){
initComponents();
loadOtherData();
this.setVisible(true);
}
void submit(){
addRecord();
this.dispose()
dataEntryDone.countDown();
}
4

1 回答 1

2

为 dataEntryFrame 使用新线程并阻塞 mainFrame 违背了 Swing 线程模型。在 Swing 中,对 Swing 中 UI 组件的所有调用都必须在 Event Dispatch Thread 上进行。为了验证在开发过程中是否发生了这种情况,您可以安装一个重绘管理器,如果它检测到正在从另一个线程使用 UI 组件,则会引发异常。请参阅 FEST -测试在 EDT 中完成对 GUI 组件的访问。为了确保在 EDT 上发生某些事情,您使用SwingUtilities.invokeAndWait /invokeLater。

您的主框架不需要(也不应该!)等待数据输入框架,而不是 CountDownLatch,让您的数据输入框架在完成后向 MainFrame 触发一个事件,以便 MainFrame 可以采取适当的操作,例如刷新列表。

只是为了进一步混淆水域,将数据保存到数据库并获取列表的数据最好不要在事件调度线程上完成。相反,使用SwingWorker在它们自己的线程中执行这些操作。但是,与必须从 EDT 访问所有 UI 组件的规则不同,此后台处理规则并不严格且快速,但建议维护响应式 UI - 如果与数据库之间的数据传输需要任何时间长度并且它在 UI 线程 (EDT) 上完成,然后 UI 将冻结。

于 2010-05-30T23:29:47.257 回答