简体   繁体   English

如何为 Runnable 类添加断点

[英]How to add breakpoints to Runnable classes

My while(true) is only running once, so I'm trying to add breakpoints to see what's going on, but they never seem to be reached within my run() .我的while(true)只运行一次,所以我试图添加断点以查看发生了什么,但它们似乎从未在我的run()到达。 I'm using IntelliJ.我正在使用 IntelliJ。 In the debugger there's a "Threads" tab.在调试器中有一个“线程”选项卡。 Do I need to do something in that tab like select the right thread in order for my breakpoint to be reached?我是否需要在该选项卡中执行某些操作,例如选择正确的线程才能到达断点? I also see thread names and am wondering how I can find the right thread in this list.我还看到线程名称,想知道如何在此列表中找到正确的线程。

public class MyClass extends ServerWorkflowProcess<OtherClass> {

    private ExecutorService executorService = Executors.newSingleThreadExecutor();

    ...

    @Override
    public void bootup() {
        logger.info("Booting up: " + this);

        BackgroundProcess backgroundImpositioner = new BackgroundProcess(this.getCollection());
        executorService.submit(backgroundImpositioner);
    }

    @Override
    public void shutdown() {
        executorService.shutdown();
    }
}

Background process后台进程

public class BackgroundProcess implements Runnable {

    protected volatile Logger logger = Logger.getLogger(BackgroundImpositioner.class.getName());

    Collection<ImpositionWorkstation> impositionWorkstations;

    public BackgroundImpositioner(Collection<ImpositionWorkstation> impositionWorkstation) {
        this.impositionWorkstations = impositionWorkstation;
    }

    public void run() {
        while(true) {
            logger.info("looping");
            for (ImpositionWorkstation workstation : impositionWorkstations) {
                if (workstation.canAcceptWork()) {

                    //go do work in another thread so we're not blocking this
                    workstation.getWorkFromQueue();
                    try {
                        workstation.doWork();
                    } catch (ImpositionException e) {
                        logger.severe(e.getMessage());
                    }
                }
            }

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
                logger.severe("Background impositioner was interrupted");
            }
        }
    }
}

Side note: the console shows "looping", so I know it gets executed once.旁注:控制台显示“循环”,所以我知道它被执行一次。 The breakpoint never gets hit and it doesn't execute more than once.断点永远不会被击中,也不会执行多次。

It happened to me once that i couldn't make Intellij Idea stop in breakpoints.我曾经遇到过我无法让 Intellij Idea 在断点处停止的情况。 Basically the problem is that once a thread is stopped in a breakpoint the others won't stop.基本上问题在于,一旦一个线程在断点处停止,其他线程就不会停止。

There is a setting in the breakpoints properties dialog that prevents this.断点属性对话框中有一个设置可以防止这种情况发生。

Right click on a breakpoint and select 'View Breakpoints'.右键单击断点并选择“查看断点”。

On the dialog select a breakpoint.在对话框中选择一个断点。

You will notice on the right of suspend checkbox 2 radio buttons: All and Thread .您会注意到挂起复选框的右侧有 2 个单选按钮: AllThread Select All .全选 Aditionally you can make that the default ( Make Default button on the right).另外,您可以将其设为默认值(右侧的“设为默认值”按钮)。 The default value will be used for any new breakpoints you add.默认值将用于您添加的任何新断点。 The old ones need to be changed manually.旧的需要手动更改。

EDIT Additional info on the Intellij help site: Breakpoint options编辑Intellij 帮助站点上的附加信息: 断点选项

断点对话框

Don't let exceptions slip through silently.不要让异常悄悄溜走。 Use the Future returned by the submit method.使用submit方法返回的Future

Future<?> f=executorService.submit(backgroundImpositioner);
try {
  f.get();
} catch(Exception ex) {
  ex.printStackTrace();
}

Then you know more.然后你知道更多。

The code above is just for finding your actual problem.上面的代码只是为了找到你的实际问题。 For production environments you wouldn't wait for completion but rather log the exception when it occurred, eg:对于生产环境,您不会等待完成,而是在异常发生时记录异常,例如:

executorService.execute(new FutureTask<Object>(backgroundImpositioner, null)
{
  @Override
  protected void done() {
    if(!isCancelled()) try {
      get();
    } catch(InterruptedException ex) {
      throw new AssertionError("on completed task", ex);
    } catch(ExecutionException ex) {
      logger.log(Level.SEVERE, "in background task", ex.getCause());
    }
  }
});

出于某种原因,我无法在while(true)行中设置断点,但可以在run()其他位置删除断点。

If there's no exception thrown inside the run method, i can only assume that one of the calls never returns.如果 run 方法中没有抛出异常,我只能假设其中一个调用永远不会返回。

Can you put output statements after every single call to see how far you get?你能在每次调用后放置输出语句来看看你能走多远吗? I guess either workstation.canAcceptWork() or workstation.doWork() is the culprit.我猜workstation.canAcceptWork()workstation.doWork()是罪魁祸首。

I've met a similar problem that IntelliJ never hits my breakpoint in the run() method of a Runnable class.我遇到了一个类似的问题,即 IntelliJ 从未在 Runnable 类的 run() 方法中命中我的断点。 I found that the only position for the breakpoint to be hit is at the line of public void run() { .我发现断点的唯一位置是在public void run() {

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM