主线程在等待时,不会执行并发线程中的操作

时间:2011-04-07 08:13:12

标签: java eclipse events swing concurrency

我有一个使用临时表(存在于用户会话范围内)和复杂数据处理的应用程序。

出于调试目的,我需要在应用程序处理期间对此临时表执行查询。

我添加了一些额外的逻辑作为方面(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


    }
});

2 个答案:

答案 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事件线程停止。 我已经纠正了切入点的消息并且问题消失了。 谢谢大家。