4

我正在尝试实现一个代码,我想从 JNI 调用一个应该有超时的函数。如果超过超时,我想终止本机任务。我发布了一段代码作为示例。

void myFunction(timeOutInSeconds)
{
    if(timeOutInSeconds > 0)
    {
        ExecutorService executor = Executors.newCachedThreadPool();
        Callable<Integer> task = new Callable<Integer>() {
            public Integer call() {
                System.out.println("Calling JNI Task");
                JNI_Task();
                System.out.println("Finished JNI Task");
                return 0;                              
            }
        };

        Future<Integer> future = executor.submit(task);
        try 
        {
            @SuppressWarnings("unused")
            Integer result = future.get(timeOutInSeconds, TimeUnit.SECONDS); 
        } 
        catch (TimeoutException ex)
        {
            // handle the timeout               
            kill_task_in_JNI();     

            // future.cancel(true);
            return TIMEOUT;

        } catch (InterruptedException e) {
            // handle the interrupts
        } catch (ExecutionException e) {
            // handle other exceptions
        } 
        finally 
        {
            // future.cancel(true);
            executor.shutdown();
        }
    }
    else
        JNI_Task();
}

有几个问题——

  • 我应该把future.cancel()放在哪里。有 2 个位置被评论。
  • 如果我在 timeOutInSeconds = 0 的情况下运行此函数,它会完美运行。然而,无论 timeOutInSeconds 的值如何,任务都会被卡住并且不会调用 JNI 任务。我通过将 printf 放在 JNI 代码中来检查这一点。该任务需要 1 秒才能执行,我给了 30 秒、5 分钟等,但它仍然卡住了。

这种方法有什么问题吗?

4

1 回答 1

3

您可以(并且在这种情况下应该)future.cancel()仅在 finally 块中调用。http://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html

关于第二个问题,我不清楚 timeOutInSeconds = 0 时是否也会出现问题。是这样吗?能否提供 JNI_TASK() 方法的内容?

于 2012-05-29T15:36:13.800 回答