java - 我可以在 JAVA 超时后终止 Runnable 吗?
问题描述
ScriptEngineManager scriptEngineMgr = new ScriptEngineManager();
ScriptEngine jsEngine = scriptEngineMgr.getEngineByName("nashorn");
Mono.fromRunnable(() -> {
System.out.println("11111");
try {
System.out.println("2222");
jsEngine.eval("print(\"hello\");while(1);");
} catch (ScriptException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("3333");
}).timeout(Duration.ofMillis(2000)).doOnError(Exception.class, e -> {
System.out.println("4444");
System.out.println(e.toString());
}).onErrorResume(Exception.class, e -> {
System.out.println("5555");
return Mono.error(e);
}).block();
System.out.println("end!!!");
这段代码永远不会结束。它显示“java.util.concurrent.TimeoutException:在'source(MonoRunnable)'中没有观察到任何项目或终端信号在2000毫秒内(并且没有配置回退)”。
我想在 2 秒内终止它,然后看到“结束!!!”。
我怎么解决这个问题?
解决方案
这是反应器的一个相当奇怪的用法 - 如果你真的想在 2 秒后超时,那么更正常/更好的方法可能是eval()
在一个新线程中生成你的线程,并interrupt()
在一段时间后处理该线程(然后InterruptedException
酌情处理.)
但是,要直接回答这个问题,您onErrorResume()
在链末尾的调用本身会返回一个(本质上是它正在处理Mono.error
的相同错误的克隆。)当您调用时,会抛出此异常。Mono
block()
相反,您可能想要返回Mono.empty()
而不是Mono.error(e)
在该onErrorResume()
块中。
推荐阅读
- ios - Swift 符合协议子类
- drupal - Drupal 菜单链接到外部站点
- c# - 使用通用标签从 XML 获取特定数据
- php - 将逗号分隔值更改为换行符
- javascript - 无法使用 npm 安装任何软件包
- kubernetes - 如何从 K8 pod 向同一集群中的 NodePort 服务发出 HTTP 请求
- c++ - OpenCV 4.0 中的 cvCreateMat
- python - Inkscape 在访问内置扩展时不断询问“lmxl 包装器”,无论如何
- java - 如何在 docker run 命令中将 Java 选项/变量传递给 Springboot 应用程序
- bazel - Bazel:BUILD 片段需要根据目标操作系统而有所不同