如何停止线程继续执行无限循环

5
我有一种方法,在Groovy脚本执行完毕后返回HTTP响应。我创建了一个匿名线程来执行Groovy脚本。但出于预防措施,我想要该线程在3秒后停止,以防止糟糕的脚本(如:无限循环)继续运行。
public Response runScript(String script) {
    GroovyShell shell = new GroovyShell();
    Thread thread = new Thread() {
       public void run() {
           Script validatedScript = shell.parse(script);
           validatedScript.run();
       }
    };
    thread.start();
    thread.join(3000);
    return Response.ok("It ran!", MediaType.TEXT_PLAIN).build();
}

这段代码对于没有无限循环的脚本工作得很好。然而,如果存在无限循环,响应“它运行了!”将被发送到客户端,但线程仍然存活。在join()后如何终止此线程?


1
https://dev59.com/02025IYBdhLWcg3wHR8Y - tim_yates
3个回答

3
如果脚本不可信,并且您不能保证它的行为良好,那么您不能使用中断,因为这需要被取消线程的合作(通过显式检查标志 Thread.currentThread().isInterrupted 或进入 sleep、wait 或 join 的调用(即使代码可以以不友好的方式压制 InterruptedException))。
您只能通过调用 Thread#stop 来终止它。
thread.join(3000);
if (thread.isAlive()) {
    thread.stop();
}

因为stop方法可能会使终止的线程处于不良状态,而ThreadDeath异常可以在任何地方抛出,所以没有好的方法来确保停止的线程在退出之前有机会进行清理。但是,由于类似这种情况,stop方法尚未从API中删除,而且似乎不太可能在短期内删除此方法。

这里的弃用并不意味着“此方法将在以后的版本中删除”,而是“危险,请勿使用,除非您知道自己在做什么”。


0

只需检查线程是否活着:

Thread thread = new Thread()
    thread.join(3000)

    if (thread.isAlive()) {
        thread.interrupt()
        // TODO
    } else {
        // TODO
    }

0

不幸的是,除非您的脚本中有阻塞操作,否则interrupt()方法将无法帮助您。只有在线程被阻塞时,interrupt()方法才会中断线程。

您不能随意终止正在运行的线程。 您可以使用thread.isAlive()方法检查线程是否仍在工作,但您无法停止它。

我建议您尝试修改script.run(),以便最终结束,并且永远不会达到无限线程工作的状态。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接