如何阻止线程继续执行死循环

How to stop thread from continuing to execute infinite loop

我有一个方法可以在 Groovy 脚本执行后 return 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();
}

此代码适用于没有无限循环的脚本。但是,如果出现死循环,响应"It ran!"被传递给了客户端,但是线程还活着。如何在 join() 之后终止此线程?

如果脚本不受信任并且您不能依赖它表现良好,那么您不能使用中断,这需要被取消的线程的合作(通过显式检查标志 Thread.currentThread().isInterrupted 或通过调用睡眠、等待或加入(即使这样,代码也会以无用的方式压制 InterruptedException))。

您只能通过对其调用 Thread#stop 来终止它:

thread.join(3000);
if (thread.isAlive()) {
    thread.stop();
}

停止方法已被弃用,因为它会使已终止线程的 activity 处于不良状态; ThreadDeath 可以在任何地方抛出,因此没有好的方法来确保停止的线程在退出之前有机会进行清理。但是,由于这种情况,停止方法尚未从 API 中删除,并且似乎不太可能很快删除此方法。

这里的弃用并不意味着 "this method will be removed in a later version" 而是 "danger, don't use this unless you know what you're doing"。

只检查线程是否存活:

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

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

不幸的是,interrupt() 方法对您没有帮助,除非您的脚本中包含阻塞操作。 interrupt() 方法仅在线程被阻塞时才中断线程。

你不能像那样终止一个 运行 线程。 您可以使用 thread.isAlive() 方法检查线程是否仍在工作,但您无法停止它。

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