在JAVA中超时后可以终止Runnable吗?

问题描述 投票:0回答:1
        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.Did not observe any item or terminal signal within 2000ms in 'source(MonoRunnable') (and no fallback configured)"。Did not observe any item or terminal signal within 2000ms in 'source(MonoRunnable)' (and no fallback has been configured)"。

我想在2秒内终止它,然后看到 "end!!!"。

如何解决这个问题?

java spring spring-boot spring-webflux reactive
1个回答
1
投票

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

然而,直接回答这个问题,你的 onErrorResume() 在链尾的调用本身就返回一个 Mono.error (本质上是同一个错误的克隆。) Mono 它所处理的。) 当你调用 block(), 这个异常就会被抛出.

相反,你可能想返回 Mono.empty() 而非 Mono.error(e) 在那 onErrorResume() 块。


0
投票

我是这样苏维埃的。但我不确定这是不是一个好办法。我在等待更好的主意。

        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();

© www.soinside.com 2019 - 2024. All rights reserved.