Arhn - архитектура программирования

Java: обнаружение блокировки в неявных очередях во время отладки точки останова

У меня есть приложение Java, которое обрабатывает поток данных из данных, поступающих через последовательный порт, и отображает сводку в пользовательском интерфейсе Swing.

Это работает нормально, но когда я устанавливаю точки останова в Eclipse в определенных потоках (например, в потоке отправки событий Swing), у меня есть ограниченное количество времени, прежде чем JVM остановится: входящие данные все еще обрабатываются, и некоторая системная очередь , будь то очередь данных или очередь событий, переполняется.

Можно ли каким-либо образом обнаружить это в восходящих потоках, чтобы моя восходящая обработка начала отбрасывать данные во время отладки?

Если моя программа явно использует очередь, я могу просто выбросить данные, когда размер очереди станет слишком большим.

Но я не могу этого сделать, если очередь "неявная", например. им управляет какое-то другое программное обеспечение, находящееся вне моего прямого контроля. Я могу думать о двух возможностях:

  1. Если я использую SwingUtilities.invokeLater() или другой фреймворк пользовательского интерфейса, который вызывает SwingUtilities.invokeLater(), как я могу определить, резервируется ли поток Dispatch с событиями?

  2. Если я использую ExecutorService.submit(), как определить, резервируется ли очередь задач исполнителя?


обновление: я думаю, что решил # 2, обернув свой ExecutorService:

AbstractPipelineExecutor.java:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.RejectedExecutionException;

/**
 * pipeline executor
 */
abstract public class AbstractPipelineExecutor {
    /**
     * a pipeline scheduled item
     */
    public interface Task extends Runnable
    {
        /**
         * if item cannot be run, this is called instead
         */
        public void denied();
    }

    final private ExecutorService executor;

    public AbstractPipelineExecutor(ExecutorService executor)
    {
        this.executor = executor;
    }

    /**
     * submit an item to be executed
     * @param task pipeline item
     */
    public Future<?> submit(final Task task)
    {
        Future<?> result = null;
        if (this.executor.isShutdown())
        {
            task.denied();
        }
        else
        {
            try
            {
                onSubmit(task);
                result = this.executor.submit(new Runnable() {
                    @Override public void run()
                    {
                        onBeginExecute(task);
                        try
                        {
                            task.run();
                        }
                        catch (RuntimeException e)
                        {
                            onExecutionException(task, e);
                        }
                        finally
                        {
                            onEndExecute(task);
                        }
                    }
                });
            }
            catch (RejectedExecutionException e)
            {
                task.denied();
            }
        }
        return result;
    }


    /**
     * event handler: item is submitted
     * @param task pipeline item 
     */
    abstract protected void onSubmit(Task task) throws RejectedExecutionException;
    /**
     * event handler: item execution is begun
     * @param task pipeline item 
     */
    protected void onBeginExecute(Task task) {}
    /**
     * event handler: item throws a runtime exception
     * @param task pipeline item 
     */
    protected void onExecutionException(Task task, RuntimeException e) {
        throw(e);
    }
    /**
     * event handler: item execution is ended
     * @param task pipeline item 
     */
    protected void onEndExecute(Task task) {}
}

BoundedPipelineExecutor.java:

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.RejectedExecutionException;

public class BoundedPipelineExecutor extends AbstractPipelineExecutor {

    public BoundedPipelineExecutor(ExecutorService executor, int bound) {
        super(executor);
        this.q = new ArrayBlockingQueue<Task>(bound);
    }

    final private ArrayBlockingQueue<Task> q; 

    @Override public void onSubmit(Task task)
    {
        if (!this.q.offer(task))
            throw new RejectedExecutionException(task.toString());
    }
    @Override public void onBeginExecute(Task task)
    {
        this.q.remove();
    }
}

Ответы:


1

Вместо того, чтобы использовать SwingUtilities.invokeLater непосредственно из ваших классов ввода-вывода, я бы посоветовал им обновить «обобщающий», который может принимать обоснованные решения об обновлении пользовательского интерфейса. Даже без точек останова отладки вы не хотите, чтобы тяжелые операции ввода-вывода переполняли ваш пользовательский интерфейс.

Итак, создайте класс, который получает и обрабатывает ваши данные, и разрешите вашему пользовательскому интерфейсу запрашивать эту информацию с подходящими интервалами.

07.03.2011
  • спасибо, но (а) я уже разбиваю свое приложение на класс модели + представления, поэтому я не вызываю операции пользовательского интерфейса из своих классов ввода-вывода, и (б) опрос пользовательского интерфейса или его отсутствие не является проблемой. У меня есть информация, которая поступает и должна быть либо обработана + поставлена ​​в очередь, либо выброшена. При нормальной работе все нормально. Но когда я отлаживаю его и останавливаюсь в точке останова, я получаю тупик. 07.03.2011
  • Справедливо. Ваше описание проблемы предполагает, что поток диспетчеризации событий Swing каким-то образом участвовал в очистке очередей. Не могли бы вы выполнить отладку, создав фиктивный источник данных, который можно воспроизвести из реальных данных и при необходимости остановить? 07.03.2011
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..