Java:在断点调试期间在隐式队列中检测到 "gridlock"

标签 java multithreading debugging queue

我有一个 Java 应用程序,它处理来自通过串行端口到达的数据的数据流,并在 Swing UI 中显示摘要。

它工作正常,但是当我在 Eclipse 中的某些线程(例如 Swing 事件调度线程)中设置断点时,在 JVM 爬行停止之前我有有限的时间:传入数据仍在处理中,并且一些系统队列,无论是数据队列还是事件队列,都变得过满。

有什么方法可以在上游线程中检测到这一点,以便我的上游处理在调试期间开始丢弃数据?

如果我的程序明确使用队列,我可以在队列过大时丢弃数据。

但是如果队列是“隐含的”,我就不能这样做,例如它由我无法直接控制的其他软件管理。我可以想到两种可能性:

  1. 如果我使用 SwingUtilities.invokeLater() ,或者另一个调用 SwingUtilities.invokeLater() 的 UI 框架,如何检测 Dispatch 线程是否有事件备份?

  2. 如果我使用 ExecutorService.submit() ,如何检测执行者的任务队列是否有备份?


更新:我想我已经通过包装我的 ExecutorService 解决了#2:

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) {}
}

有界管道执行器.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();
    }
}

最佳答案

与其直接在您的 IO 类中使用 SwingUtilities.invokeLater,我建议他们应该更新一个“summariser”,它可以就更新 UI 做出明智的决定。即使没有调试断点,您也不希望繁重的 IO 操作淹没您的用户界面。

因此,创建一个类来接收和处理您的数据,并允许您的用户界面以适当的时间间隔轮询该信息。

关于Java:在断点调试期间在隐式队列中检测到 "gridlock",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4595260/

相关文章:

java - 推荐代码重用

java - maven cxf-codegen-plugin XMLStreamException 错误 : Attribute limit

java - 调试 eclipse/jdt jar 文件中的类方法

c++ - 如果条件在调试器/运行时评估为true,但未执行 block

java - 什么是帮助调试 Java 的有效方法/工具?

java - 在 OnFocusChanged Listener 中保持对 Edittext 的关注

java - 过期后自动删除数据库行

c# - 检测线程内的 bool 值变化

Java Thread() sleep 问题

windows - Cocoa、Windows 和线程?