【问题标题】:Can I terminate Runnable after timeout in JAVA?我可以在 JAVA 超时后终止 Runnable 吗?
【发布时间】:2020-09-22 20:51:43
【问题描述】:
        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 秒后终止它,然后看到“结束!!!”。

我该如何解决这个问题?

【问题讨论】:

    标签: java spring spring-boot spring-webflux reactive


    【解决方案1】:

    这是反应堆的一个相当奇怪的用法 - 如果你真的想在 2 秒后超时,那么更正常/更好的方法可能是在一个新线程中生成你的 eval(),然后在一个新线程中生成 interrupt()特定时间(然后酌情处理InterruptedException。)

    但是,要直接回答这个问题,您在链末尾的 onErrorResume() 调用本身会返回一个 Mono.error(本质上是它正在处理的相同错误 Mono 的克隆。)当您调用 @987654329 @, this exception is then thrown.

    相反,您可能希望在 onErrorResume() 块中返回 Mono.empty() 而不是 Mono.error(e)

    【讨论】:

    • @Berry 令人印象深刻的答案.. 看到你非常频繁和快速地回答反应/webflux。你能推荐一些好的资源来学习同样的东西吗?谢谢!
    • @AdityaRewari 没有击败反应堆参考文档开始 :-) projectreactor.io/docs/core/release/reference
    • 非常感谢您的评论。我像你的帮助一样解决了它
    【解决方案2】:

    我是这样解决的。但我不确定这是一个好方法。 我正在等待任何更好的想法。

            ScriptEngineManager scriptEngineMgr = new ScriptEngineManager();
            ScriptEngine jsEngine = scriptEngineMgr.getEngineByName("nashorn");
    
            String script = "$result.test = 1;\nwhile(1);";
            Thread th = new Thread(() -> {
                jsEngine.put("$result", new JSONObject());
                try {
                    jsEngine.eval(script);
                } catch (ScriptException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            });
    
            Mono.defer(() -> {
                th.start();
                try {
                    th.join();
                } catch (InterruptedException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                return Mono.just(true);
            }).timeout(Duration.ofSeconds(2)).doOnError(TimeoutException.class, e -> {
                // e.printStackTrace();
                System.out.println(th.isAlive());
                th.stop();
            }).doAfterTerminate(() -> {
                System.out.println(result);
                System.out.println("end!!!");
                System.out.println(th.isAlive());
            }).onErrorReturn(false).block();
    
    

    【讨论】:

      猜你喜欢
      • 2011-02-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-24
      • 1970-01-01
      • 2011-09-26
      • 2020-09-03
      相关资源
      最近更新 更多