我有一个使用临时表(存在于用户会话范围内)和复杂数据处理的应用程序。
出于调试目的,我需要在应用程序处理期间对此临时表执行查询。
我添加了一些额外的逻辑作为方面(AspectJ)并在Eclipse中运行我的应用程序作为加载时编织应用程序(使用AJDT / JDT编织插件)。
我执行以下操作:在获得新连接后,我使用gui创建另一个线程并将连接传递给它(稍后将对此进行描述)。
在每次查询之后,主应用程序线程等待来自gui线程的消息继续工作(这使我有机会进行查询并在临时表中查看中间结果)。使用BlockingQueue实现消息传递。
在GUI中我有一个带有查询文本区域的框架和两个按钮“运行查询”和“释放主线程”。
我想按“运行查询”按钮将执行查询并在框架上显示结果。然后按“释放主线程”按钮将消息发送到主线程以继续工作。
问题是当主线程正在等待blockingQueue.take()时,按下“运行查询”按钮会导致帧冻结并且什么也不做(看起来gui变得没有响应)。
当主线程正在等待blockingQueue.take()时,“释放主线程”分叉很好(但不是在“运行查询”后按下)。
当主线程正在运行时(我在队列中放入了大量对象),“运行查询”按钮正常工作,我可以看到查询结果。
起初我尝试过使用EDT和事件调度进行操作,但没有任何帮助我。你对这个问题有任何想法吗?
//aspect on 'newConnection' pointcut
after() returning (final Connection connection): newConnection() {
gUI = new Runnable() {
public void run() {
new GuiView(blockingQueue, connection);
}
};
SwingUtilities.invokeLater(gUI);
}
//GuiView code extract for button with query data retrieval action
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
try {
ResultSet rs = ConnectionManipulator.executeStatement(
queryTextAreaG.getText()
);
///....result parsing logic
} catch (SQLException e1) {
JOptionPane.showMessageDialog(null, "Exception!");
} finally {
}
//....result out logic
}
});
答案 0 :(得分:0)
GUI通常在主线程中运行(不仅在Java上运行),所以如果你让主线程阻塞,你也会阻止你的GUI并冻结。
修改强>
我认为你的SwingUtilities.invokeLater错了:它被用来执行主事件循环线程中的部分代码,所以通常是从后台线程调用,而不是相反。现在看起来查询正在事件循环线程中执行,从而阻止了GUI。
让查询在普通线程中执行,当它准备就绪时,使用SwingUtilities.invokeLater调用mainthread回调。
答案 1 :(得分:0)
抱歉,麻烦。问题在于错误的切入点描述(未附加到上面的代码中)。 我有这个切入点:
PreparedStatement around(): prepareStatement() {
if (gUI != null) {
try {
blockingQueue.take();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
}
}
return proceed();
但 ConnectionManipulator.executeStatement 也使用prepareStatement()。 因此它执行blockingQueue.take(),这会导致GUI事件线程停止。 我已经纠正了切入点的消息并且问题消失了。 谢谢大家。