gpt4 book ai didi

Java:杀死由 ExecutorService 作为 Runnable 启动的线程

转载 作者:塔克拉玛干 更新时间:2023-11-02 07:44:35 24 4
gpt4 key购买 nike

我有一个系统,当它收到来自网络服务的调用时,它会启动工作人员。 worker 由 ExecutorService 启动,启动的类实现 Runnable。但是,如果工作人员超时,我无法真正杀死工作人员,这会导致我的系统出现资源问题。

public class MyClass implements Runnable {

public void internalCall() {
logger.info("B-1");
//Some business code which may take too long
// <...>
logger.info("B-2");
}

public void launch() {
// Wrapper
Callable<Object> callable = new Callable<Object>() {
@Override
public Object call() throws Exception {
internalCall();
return null;
}
};

// Submit
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Object> future = executor.submit(callable);

try {
// Wait
future.get(1, TimeUnit.SECONDS);
}
catch (TimeoutException e) {
logger.warn("Timeout");
}
finally {
logger.info("A-1");
executor.shutdownNow();
future.cancel(true);
logger.info("A-2");
}
}
}

如果工作人员超时,我会收到以下日志消息:

INFO | B-1
WARN | Timeout
INFO | A-1
INFO | A-2

随后服务保持空闲状态,直到另一个工作人员请求进来。然而,尽管分别在 ExecutorService 和 Future 上调用了 shutdownNow() 和 cancel(),工作人员继续:

INFO | B-1
WARN | Timeout
INFO | A-1
INFO | A-2
INFO | B-2

我环顾四周,发现有许多其他类似的关于终止线程的问题,普遍的共识是您不应该这样做。然而,这是一个可以扩展的类,目的是覆盖 internalCall() - 这意味着我不能依赖 internalCall 来监管自己并检查 Thread.isInterrupted() 或类似的东西。

我想通过攻击 furure 或 executor 对象来强制从 launch() 方法中杀死东西。

最佳答案

注意

What if a thread doesn't respond to Thread.interrupt?

In some cases, you can use application specific tricks. For example, if a thread is waiting on a known socket, you can close the socket to cause the thread to return immediately. Unfortunately, there really isn't any technique that works in general. It should be noted that in all situations where a waiting thread doesn't respond to Thread.interrupt, it wouldn't respond to Thread.stop either. Such cases include deliberate denial-of-service attacks, and I/O operations for which thread.stop and thread.interrupt do not work properly. - Java Thread Primitive Deprecation

那么我们学到了什么...在 Java 中,不要运行您确实不能信任的第三方代码,与您的主要应用程序执行相同的执行。此外,即使 Thread.stop 确实有效,您仍然有一大堆其他事情比线程不检查中断状态(即代码调用 System.exit(0))更糟糕。

我建议您对您不信任的第三方代码执行的操作是:

  • 将第三方代码作为由您控制其执行的 Java 运行的评估语言运行。一些示例是:像 Drools 这样的规则语言或像 JMustache 这样的无逻辑模板语言。

  • 在单独的执行中运行第三方代码,并使用您的操作系统杀死进程和用于通信的套接字等 IPC。

关于Java:杀死由 ExecutorService 作为 Runnable 启动的线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29884262/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com