停止执行Java线程以及join()的作用 [英] stopping execution of java thread and the role of join()

查看:221
本文介绍了停止执行Java线程以及join()的作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的程序分析了大量文档,偶尔会得到导致无限循环或很长循环的页面.这是无法预先分析的.我想杀死特定页面并继续下一个页面(丢弃有问题页面的任何结果).我已阅读这样的答案 如何在Java中经过一定时间后停止执行? /a>并编写了以下代码:

My program analyzes a large number of documents and occasionally gets a page that causes an infinite or very long loop. This is not analyzable in advance. I want to kill the particular page and continue with the next one (throwing away any results for the offending page). I have read SO answers such as this How to stop execution after a certain time in Java? and have written the following code:

// main program 
    private void runThread() throws InterruptedException {
        long timeout = 15000L;
        RunPageAnalyzer runPageAnalyzer = new RunPageAnalyzer(this);
        Thread t = new Thread(runPageAnalyzer); 
        long startTime = System.currentTimeMillis();
        t.start();
        while (t.isAlive()) {
            t.join(1000);
            long delta = System.currentTimeMillis() - startTime;
            LOG.debug("delta: "+delta);
            if (delta > timeout && t.isAlive()) {
                t.interrupt();
                t.join;
                break;
            }           
        }
    }

该线程调用的同一类中的方法

the method in the same class called by the thread

    void runActions() {
        // variable length calculation which should be abandoned if too long
    }

和Runnable:

    class RunPageAnalyzer implements Runnable {
    private PageAnalyzerAction pageAnalyzerAction;
        public RunPageAnalyzer(PageAnalyzerAction pageAnalyzerAction) {
            this.pageAnalyzerAction = pageAnalyzerAction;
        }

        public void run() {
        try {
            pageAnalyzerAction.runActions();
        } catch (Exception e) {
            LOG.debug("Exception running thread ", e);
        }
    }

正常终止runActions()的输出似乎正常:

The output for a normal termination of runActions() seems OK:

    =========== page 1 =============
13863 [main] DEBUG org.xmlcml.graphics.control.page.PageAnalyzerAction  - pageActions: 24 on page 0
14863 [main] DEBUG org.xmlcml.graphics.control.page.PageAnalyzerAction  - delta: 1000
15864 [main] DEBUG org.xmlcml.graphics.control.page.PageAnalyzerAction  - delta: 2001
16864 [main] DEBUG org.xmlcml.graphics.control.page.PageAnalyzerAction  - delta: 3001
16975 [main] DEBUG org.xmlcml.graphics.control.page.PageAnalyzerAction  - delta: 3112
16975 [main] DEBUG org.xmlcml.graphics.control.page.PageAnalyzerAction  - finished page

,但是当超过时间限制时,该过程将挂在t.join()中.

but when the time limit is exceeded the process hangs in t.join().

    =========== page 2 =============
16975 [main] DEBUG org.xmlcml.graphics.control.page.PageAnalyzerAction  - pageActions: 24 on page 0
17976 [main] DEBUG org.xmlcml.graphics.control.page.PageAnalyzerAction  - delta: 1001
18976 [main] DEBUG org.xmlcml.graphics.control.page.PageAnalyzerAction  - delta: 2001
// ...
30976 [main] DEBUG org.xmlcml.graphics.control.page.PageAnalyzerAction  - delta: 14001
31976 [main] DEBUG org.xmlcml.graphics.control.page.PageAnalyzerAction  - delta: 15001

如果我省略了t.join(),则该进程的行为符合我的预期,但我担心这可能只是在建立大量的线程,这以后会出现问题.

If I omit the t.join() then the process behaves as I would expect but I am worried that this might simply be building up huge numbers of threads that will be a problem later.

更新: 到目前为止的答案表明这是不平凡的(我发现标准的Java示例/教程不是很有帮助).关键是runActions()必须明确知道它可能会被中断. join()不是主要问题,因为线程只是继续前进.

UPDATE: The answers so far have suggested that this is non-trivial (and I didn't find the standard Java examples/tutorials very helpful). The key point is that runActions() has to know explicitly that it might be interrupted. join() is not the primary problem because the threads just keep going.

其他问题: 我是否必须在runActions()的所有地方都插入Thread.currentThread().isInterrupted(),我希望它们会出现无法预测的长循环?

FURTHER QUESTION: Do I have to insert Thread.currentThread().isInterrupted() in all the places in runActions() which I expect to be in unpredictably long loops?

推荐答案

我在这里假定pageAnalyzerAction.runActions();可以被中断(即,它可以通过迅速退出来处理中断).

I assume here that pageAnalyzerAction.runActions(); can be interrupted (i.e. it handles interruptions by exiting fairly quickly).

如果您不熟悉低级线程API,则可以使用java.concurrent包中的执行程序和期货来为您处理线程管理和超时策略:

If you are not comfortable with the low level thread API, you could use an executor and futures from the java.concurrent package to deal with thread management and time out policy for you:

  • 执行程序将使用线程池处理线程管理,并在必要时重用它们.
  • 可以通过超时查询任务提交时返回的未来-如果任务未在超时内完成,未来将抛出TimeOutException,然后您可以取消任务

一个人为的例子是:

//declare an executor  somewhere in your code, at a high level to recycle threads
ExecutorService executor = Executors.newFixedThreadPool(10); //number of threads: to be adjusted

private void runThread() throws InterruptedException {
    long timeout = 15000L;
    RunPageAnalyzer runPageAnalyzer = new RunPageAnalyzer(this);
    Future future = executor.submit(runPageAnalyzer);
    try {
        future.get(timeout, TimeUnit.MILLISECONDS);
    } catch (ExecutionException e) {
        //the runnable threw an exception: handle it
    } catch (TimeoutException e) {
        //the task could not complete before the timeout
        future.cancel(true); //interrrupt it
    }
}

这篇关于停止执行Java线程以及join()的作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆