标准Java模式,用于将超时包装在错误的进程周围

Bat*_*eba 5 java concurrency

我正在使用第3方函数(例如runThird()),该函数具有无限循环的趋势,并且没有内置的超时功能。但是,我可以杀死它(killThird())。有合适的方法做到这一点(即并发构造)吗?

这是我的尝试:

java.lang.Thread thread = new Thread(new Runnable(){
    @Override
    public void run(){
        try {
            Thread.sleep(TIMEOUT);
        } catch (java.lang.InterruptedException e){
            return;
        }
        killThird();
    }
});                                
thread.start();

RunThirdResult rtr = runThird();

if (thread != null){
    thread.interrupt();
}
Run Code Online (Sandbox Code Playgroud)

但是我不确定我是否喜欢创建线程,使用睡眠的开销以及如果runThird()返回会中断线程的麻烦。

Vic*_*kin 0

类似的事情?最有趣的部分是StoppableWrapper#stop(),因为优雅取消是一件困难的事情,并且没有适用于所有情况的通用方法。一次你需要清除文件系统,另一次需要关闭网络连接,等等。在你的示例中,你只需调用interrupt(),所以我假设runThird()很荣幸被中断,并且会注意清理其背后的东西。

class Sample {
    final ExecutorService tasksExecutor = Executors.newCachedThreadPool();

    class StoppableWrapper implements Runnable {
        private final Runnable task;
        private final CountDownLatch executed;

        StoppableWrapper(Runnable task, CountDownLatch executed) {
            this.task = task;
            this.executed = executed;
        }

        void stop() {
            // e.g. Thread.currentThread().interrupt()
        }

        @Override
        public void run() {
            task.run();
            executed.countDown();
        }
    }

    public void scheduleTimingOutTaskExecution(final long timeout) {
        final CountDownLatch executed = new CountDownLatch(1);

        final StoppableWrapper command = new StoppableWrapper(new RunThirdInstance(), executed);
        tasksExecutor.execute(command);
        tasksExecutor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    if (!executed.await(timeout, TimeUnit.MILLISECONDS)) {
                        command.stop();
                        // additionally, you can make stop() return boolean after time-out as well and handle failure 
                    }
                } catch (InterruptedException e) {
                    // handle stopper exception here
                }
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)