Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/377.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
围绕错误进程包装超时的标准Java模式_Java_Concurrency - Fatal编程技术网

围绕错误进程包装超时的标准Java模式

围绕错误进程包装超时的标准Java模式,java,concurrency,Java,Concurrency,我使用的是第三方函数(比如runThird()),它有无限循环的趋势,并且没有内置超时功能。但是,我可以杀死它(killThird())。有没有合适的方法来实现这一点(例如,一些并发构造) 以下是我的尝试: java.lang.Thread thread = new Thread(new Runnable(){ @Override public void run(){ try { Thread.sleep(TIMEOUT);

我使用的是第三方函数(比如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();
}

但是我不确定我是否喜欢创建线程的开销,使用sleep和在runThird()返回时中断线程的方法。

类似的东西?最有趣的部分是
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
                }
            }
        });
    }
}

让我们假设
runThird()
retuns Integer

// ...  in your class ...
private ExecutorService executor = Executors.newCachedThreadPool();


//... then somewhere, where you want to call runThird()
Future<Integer> handle = executor.submit( new Callable<Integer>(){
    @Override Integer call(){
         return runThird(); // Assume you made it available here ...
    }
}

Integer result;
try{
   result = handle.get(TIMEOUT,UNIT); // TIMEOUT and UNIT declared somewhere above ...
}
catch(TimeoutException ex) {
   killThird();
   // HANDLE result not being set!
}

// ... use result.
/。。。在你们班上。。。
私有ExecutorService executor=Executors.newCachedThreadPool();
//... 然后在某个地方,您想调用runThird()
Future handle=executor.submit(new Callable()){
@重写整数调用(){
return runThird();//假设您在这里提供了它。。。
}
}
整数结果;
试一试{
result=handle.get(超时,单位);//在上面某处声明超时和单位。。。
}
捕获(TimeoutException例外){
killThird();
//处理未设置的结果!
}
//…使用结果。

我将为此使用ScheduledExecutorService。计划将其终止

volatile RunThirdResult rtr;

ScheduledExecutorService service = Executors.newScheduledThreadPool(1);

service.schedule(new Runnable(){
   public void run(){
      if(rtr == null) killThird();
   }
}, TIMEOUT_IN_MILLIS, TimeUnit.MILLISECONDS);

RunThirdResult rtr = runThird();

您可以使用ExecutorService、Future和Callable(如果没有返回值,Runnable就足够了)。您可以向Executor提交一个Callable(运行
third()
),在返回的Future上,您将使用timeout进行阻塞。请注意,您可以使用
TimeUnit.SECONDS.sleep(xx)
,它比普通的
线程更容易被眼睛看到。sleep(xx)
;)您的第三方方法是否运行结果?@fge,是的,第三方确实返回结果。我来修正这个问题,复杂吗?我将提交一个
newcallable(){public V call(){return runThird();}}
然后
get(TIMEOUT,UNITS)
关于结果的未来,并在
catch(TimeoutException)
中提交。(当然,正确地替换了“V”)。是的,很好,但是上面的代码在停止任务时提供了更大的灵活性——您有
stop()
方法,您可以使用适当的关闭逻辑覆盖该方法。也许,OP在这种特殊情况下不需要它,但我在编写示例时是这样想的。+1比我的建议还要短,并且没有使用异常。不错……但是根据runThird/killThird的实现,可能会有副作用,对吗?如果我连续叫两次会怎么样?第一个呼叫的预定终止可能终止第二个呼叫。嗯,取决于具体实现,我不知道。“但它可以。”费尔多是的,你是对的。我们的两个实现都遭受相同的命运。除非OP提供更多信息,否则在我看来,没有什么其他可以假设的。