Действие в параллельном потоке не выполняется, когда основной поток ожидает - PullRequest
0 голосов
/ 07 апреля 2011

У меня есть приложение, которое использует временные таблицы (существовавшие в рамках сеанса пользователя) и комплексную обработку данных.

В целях отладки мне нужно выполнять запросы к этим временным таблицам во время обработки приложения.

Я добавил некоторую дополнительную логику в качестве аспектов (AspectJ) и запустил свое приложение как ткацкое приложение во время загрузки в Eclipse (используя плагин ткачества AJDT / JDT).

Я делаю следующее: после получения нового соединения я создаю другой поток с графическим интерфейсом и передаю ему соединение (будет описано позже).

После каждого запроса основной поток приложения ожидает сообщения от потока графического интерфейса, чтобы продолжить работу (что дает мне возможность выполнять запросы и видеть промежуточные результаты во временных таблицах). Обмен сообщениями осуществляется с помощью BlockingQueue.

В графическом интерфейсе у меня есть рамка с текстовой областью для запроса и две кнопки «Выполнить запрос» и «Освободить основной поток».

Я хотел, чтобы нажатие кнопки «Выполнить запрос» выполняло запрос и показывало результаты во фрейме. А нажатие на кнопку «Освободить основную ветку» отправит сообщение в основную ветку для продолжения работы.

Проблема в том, что когда основной поток ожидает blockingQueue.take (), нажатие кнопки «Выполнить запрос» приводит к зависанию кадра и ничего не делать (похоже, графический интерфейс перестает отвечать на запросы).

Когда основной поток ожидает blockingQueue.take (), «Release main thread» отлично разветвляется (но не после нажатия «Run query»).

Когда основной поток работает (я поместил много объектов в очередь), кнопка «Выполнить запрос» работает нормально, и я вижу результаты запроса.

Сначала я попробовал манипуляции с 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 голосов
/ 08 апреля 2011

Извините, за беспокойство. Проблема была в неверном описании pointcut (не прикрепленном к коду выше). У меня была эта точка отсчета вокруг:

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

            }
        }
return proceed(); 

Но ConnectionManipulator.executeStatement также использует prepareStatement (). Поэтому он выполняет blockingQueue.take (), что приводит к остановке потока событий графического интерфейса. Я исправил описание pointcut, и проблема исчезла. Спасибо всем.

0 голосов
/ 08 апреля 2011

Графические интерфейсы обычно выполняются в основном потоке (не только в Java), поэтому, если вы разрешите блокировать основной поток, вы также заблокируете графический интерфейс, и он зависнет.

EDIT

Я думаю, что вы неправильно поняли SwingUtilities.invokeLater: он используется для выполнения части кода в основном потоке цикла событий, поэтому обычно вызывается из фонового потока, а не наоборот. Теперь похоже, что запрос выполнялся в потоке цикла событий, блокируя таким образом графический интерфейс.

Пусть запрос будет выполнен в обычном потоке, и когда он будет готов, вызовите функцию обратного вызова mainthread, используя SwingUtilities.invokeLater.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...