开发者

Java: how to ensure an interface method doesn't take more time than X?

开发者 https://www.devze.com 2023-01-10 02:39 出处:网络
I have an interface method boolean right(), if it isn\'t \"answering\" in a s开发者_StackOverflow中文版econd, it should return false.Yes, this is possible with e.g. java.util.concurrent.Future<V>

I have an interface method boolean right(), if it isn't "answering" in a s开发者_StackOverflow中文版econd, it should return false.


Yes, this is possible with e.g. java.util.concurrent.Future<V> (the standard interface to represents the result of an asynchronous computation of type V), combined with the method get(long timeout, TimeUnit unit). The method may throw TimeoutException, among other exceptions, but otherwise returns the computed result on normal execution.

In this case you want a Future<Boolean>, with get(1, TimeUnit.SECONDS) within a try-catch block, handling TimeOutException per your specification.

Available concrete implementations are FutureTask<V> and SwingWorker<T,V>. If this is within the context of Swing application, then you'd want to use the latter.

See also

  • Effective Java 2nd Edition, Item 68: Prefer executors and tasks to threads
  • Concurrent Programming with J2SE 5.0
  • Java Tutorials/Concurrency
  • Java Tutorials/Swing/How to use Threads - important read if you're using Swing!


Well, you can't put that requirement in the interface itself, but if you're controlling the calling side it's possible:

  • Spawn a new thread, in which you execute the method-call.
  • In the original thread, join with the new thread with a time out on 1000 milliseconds.
  • If the join times out, kill the thread (or disregard it's result), and return false, otherwise return the result of the call.


Ofcourse it is not possible to add this as a static check (at compile time, something that the compiler can check to ensure it), because how long it takes to run an operation heavily depends on the runtime environment that the program is running in.

You can use the classes in java.util.concurrent to run an operation and wait for it to finish within a certain timeout. A simple example (not thoroughly tested, but demonstrates the idea):

ExecutorService exec = Executors.newSingleThreadExecutor();
Future<Integer> future = exec.submit(new Callable<Integer>() {

    @Override
    public Integer call() throws Exception {
        Thread.sleep(10000);
        return 123;
    }
});

try {
    // Run the callable, wait for max. 5 seconds
    System.out.println(future.get(5, TimeUnit.SECONDS));
}
catch (TimeoutException ex) {
    System.out.println("The operation took too long!");
}


Not possible. This is implementation-specific behaviour.

0

精彩评论

暂无评论...
验证码 换一张
取 消