6

I am using the JavaMail API , and there is a method in the Folder class called "search" that sometimes take too long to execute. What i want is to execute this method over a maximum period of time( say for example 15 seconds in maximum) , that way i am sure that this method will not run up more than 15 seconds.

Pseudo Code

messages = maximumMethod(Folder.search(),15);

Do I have to create a thread just to execute this method and in the main thread use the wait method ?

Flexo
  • 87,323
  • 22
  • 191
  • 272
tt0686
  • 1,771
  • 6
  • 31
  • 60
  • Duplicate of [How do I call some blocking method with a timeout in Java?](http://stackoverflow.com/questions/1164301/how-do-i-call-some-blocking-method-with-a-timeout-in-java) – Daniel Pryden Aug 24 '11 at 15:15

3 Answers3

5

The best way to do this is create a single threaded executor which you can submit callables with. The return value is a Future<?> which you can get the results from. You can also say wait this long to get the results. Here is sample code:

    ExecutorService service = Executors.newSingleThreadExecutor();
    Future<Message[]> future = service.submit(new Callable<Message[]>() {
        @Override
        public Message[] call() throws Exception {
            return Folder.search(/*...*/);
        }
    });

    try {
        Message[] messages = future.get(15, TimeUnit.SECONDS);
    }
    catch(TimeoutException e) {
        // timeout
    }
Amir Raminfar
  • 33,777
  • 7
  • 93
  • 123
  • +1, exactly what I was about to post. Except that I would probably recommend using `Executors.newCachedThreadPool()` instead of a single-threaded executor if you expected that you might be doing several of these calls in a row (e.g. in a loop). – Daniel Pryden Aug 24 '11 at 15:14
  • @Daniel, I thought about doing that too. :) I just went with a single thread because it was in the same scope. But I do agree if it was going to be reused, one should use the cached executors which I think defaults to 64 threads at most. – Amir Raminfar Aug 24 '11 at 15:15
1

You could

  1. mark current time
  2. launch a thread that will search in the folder
  3. while you get the result (still in thread) don't do anything if current time exceeds time obtained in 1 plus 15 seconds. You won't be able to stop the connection if it is pending but you could just disgard a late result.

Also, if you have access to the socket used to search the folder, you could set its timeout but I fear it's gonna be fully encapsulated by javamail.

Regards, Stéphane

Snicolas
  • 37,840
  • 15
  • 114
  • 173
0

This SO question shows how to send a timeout exception to the client code: How do I call some blocking method with a timeout in Java?

You might be able to interrupt the actual search using Thread.interrupt(), but that depends on the method's implementation. You may end up completing the action only to discard the results.

Community
  • 1
  • 1
Michael Brewer-Davis
  • 14,018
  • 5
  • 37
  • 49
  • `interrupt()` was my first thought, but then you're relying on the thread scheduler to send you back into the parent thread while you poll. Your parent thread would have to be `child.start(); while(true) { long now = System.cTM(); if(now - then > 15000) { child.interrupt(); break; } Thread.sleep(100); }` and you would be relying on the scheduler to each poll which is less than ideal. It would work for simple programs but if you needed something tighter it wouldn't. – corsiKa Aug 24 '11 at 15:33