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

时间:2022-03-27 06:59:01

I have an application which use temporary tables (existed in the scope of user session) and complex data processing.

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

For debug purposes I need to execute queries to this temporary tables during the application processing.

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

I added some additional logic as aspects (AspectJ) and run my application as load-time weaving application in Eclipse (using AJDT/ JDT weaving plugin).

我添加了一些额外的逻辑作为方面(AspectJ)并在Eclipse中运行我的应用程序作为加载时编织应用程序(使用AJDT / JDT编织插件)。

I do the following: after getting new connection I create another thread with gui and pass the connection to it (would be described later).

我执行以下操作:在获得新连接后,我使用gui创建另一个线程并将连接传递给它(将在后面描述)。

After each query the main application thread waiting for the message from gui thread to continue the work (that gives me an opportunity to make queries and see intermediate results in temporary tables). Messaging is implemented using BlockingQueue.

在每次查询之后,主应用程序线程等待来自gui线程的消息继续工作(这使我有机会进行查询并在临时表中查看中间结果)。使用BlockingQueue实现消息传递。

In the GUI I have a frame with text area for query and two buttons "Run query" and "Release main thread".

在GUI中,我有一个带有查询文本区域的框架和两个按钮“运行查询”和“释放主线程”。

I wanted that pressing the "Run query" button will execute the query and show the results on the frame. And pressing the button "Release main thread" will send the message to the main thread to continue the work.

我想按“运行查询”按钮将执行查询并在框架上显示结果。然后按“释放主线程”按钮将消息发送到主线程以继续工作。

The problem is when the main thread is waiting for blockingQueue.take(), pressing the button "Run query" causes the frame to freeze and do nothing (it looks like gui becomes unresponsive).

问题是当主线程正在等待blockingQueue.take()时,按下“运行查询”按钮会导致框架冻结并且什么都不做(看起来gui变得没有响应)。

When the main thread is waiting for blockingQueue.take(), "Release main thread" forks fine (but not after "Run query" pressing).

当主线程正在等待blockingQueue.take()时,“释放主线程”分叉很好(但不是在“运行查询”按下之后)。

When the main thread is running (I put plenty of objects in the queue), "Run query" button works normally and I can see query results.

当主线程正在运行时(我在队列中放入了大量对象),“运行查询”按钮正常工作,我可以看到查询结果。

At first I've tried manipulations with EDT and events dispatching, but nothing has helped me. Have you any ideas of the problem?

起初我曾尝试用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 个解决方案

#1


0  

GUIs usually run in the main thread (not only on Java), so if you let your main thread block, you block your GUI as well and it freezes.

GUI通常在主线程中运行(不仅在Java上运行),因此如果你让主线程阻塞,你也会阻止你的GUI并冻结。

EDIT

I think you got SwingUtilities.invokeLater wrong: it is being used to execute part of the code in the main event loop thread, so usually is being called from the background thread, not the other way round. Now it looks like the query were being executed in the event loop thread thus blocking GUI.

我认为你的SwingUtilities.invokeLater错了:它被用来执行主事件循环线程中的部分代码,因此通常是从后台线程调用,而不是相反。现在,看起来查询正在事件循环线程中执行,从而阻止了GUI。

Let the query be executed in a normal thread and when it is ready call the mainthread callback using SwingUtilities.invokeLater.

让查询在普通线程中执行,当它准备就绪时,使用SwingUtilities.invokeLater调用mainthread回调。

#2


0  

Sorry, for trouble. The problem was in the incorrect pointcut description (not attached to the code above). I had this the pointcut around:

对不起,麻烦。问题在于错误的切入点描述(未附加到上面的代码中)。我有这个切入点:

PreparedStatement around(): prepareStatement() {
        if (gUI != null) {
            try {
                blockingQueue.take();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            } finally {

            }
        }
return proceed(); 

But ConnectionManipulator.executeStatement uses prepareStatement() also . So it executes blockingQueue.take(), which causes the GUI event thread to stop. I`ve corrected the pointcut desription and the problem gone away. Thank you all.

但ConnectionManipulator.executeStatement也使用prepareStatement()。因此它执行blockingQueue.take(),这会导致GUI事件线程停止。我已经纠正了切入点的消息并且问题消失了。谢谢你们。

#1


0  

GUIs usually run in the main thread (not only on Java), so if you let your main thread block, you block your GUI as well and it freezes.

GUI通常在主线程中运行(不仅在Java上运行),因此如果你让主线程阻塞,你也会阻止你的GUI并冻结。

EDIT

I think you got SwingUtilities.invokeLater wrong: it is being used to execute part of the code in the main event loop thread, so usually is being called from the background thread, not the other way round. Now it looks like the query were being executed in the event loop thread thus blocking GUI.

我认为你的SwingUtilities.invokeLater错了:它被用来执行主事件循环线程中的部分代码,因此通常是从后台线程调用,而不是相反。现在,看起来查询正在事件循环线程中执行,从而阻止了GUI。

Let the query be executed in a normal thread and when it is ready call the mainthread callback using SwingUtilities.invokeLater.

让查询在普通线程中执行,当它准备就绪时,使用SwingUtilities.invokeLater调用mainthread回调。

#2


0  

Sorry, for trouble. The problem was in the incorrect pointcut description (not attached to the code above). I had this the pointcut around:

对不起,麻烦。问题在于错误的切入点描述(未附加到上面的代码中)。我有这个切入点:

PreparedStatement around(): prepareStatement() {
        if (gUI != null) {
            try {
                blockingQueue.take();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            } finally {

            }
        }
return proceed(); 

But ConnectionManipulator.executeStatement uses prepareStatement() also . So it executes blockingQueue.take(), which causes the GUI event thread to stop. I`ve corrected the pointcut desription and the problem gone away. Thank you all.

但ConnectionManipulator.executeStatement也使用prepareStatement()。因此它执行blockingQueue.take(),这会导致GUI事件线程停止。我已经纠正了切入点的消息并且问题消失了。谢谢你们。