0

I have method that uses ExecutorService to schedule tasks. I need the task to be terminated after a set amount of time. How can I specify such a time?

public String schedule(Callable<Object> task)
        {

            Future<Object> f = null;
            String status = null;
            try
            {
                f = service.submit(task);
                status = f.get(1, TimeUnit.SECONDS).toString();
            }
            catch (TimeoutException e)
            {
                status = "Waiting took too long.";
            }
            catch (Exception e)
            {
                 status = e.getMessage();
            }

            return f.toString();
        }

EDIT: I have a process that should terminate after waiting for x amount of time for a resource to become available, instead of waiting indefinitely.

nikk
  • 2,627
  • 5
  • 30
  • 51
  • 3
    you have the answer here - http://stackoverflow.com/questions/2758612/executorservice-that-interrupts-tasks-after-a-timeout – Elia Rohana Jul 13 '16 at 12:08

1 Answers1

0

This stop execution behaviour should really be implemented by the task itself. You could try to forcibly stop the thread, but that causes deadlock problems.

You should let the tasks implement the time out logic, so they can shut themselves down in an appropriate way.


Here is a basic example of a task that waits on a resource:

@Override
public Object call() throws Exception { // In a Callable<Object>
    long startTime = System.currentTimeMillis();
    while(System.currentTimeMillis() - startTime < 5000) { // wait for max 5 seconds.
        if(resource.isAvailable()) {
            // Do something with the resource
            return someValue;
        }
    }

    throw new TimeoutException("Resource could not be acquired");
}
Jorn Vernee
  • 31,735
  • 4
  • 76
  • 93
  • thanks, but I am talking about timing here. **How to set a time interval** on the executor, after which it terminates the thread. I have a process that should terminate after waiting for x amount of time for a resource to become available, instead of waiting indefinitely. – nikk Jul 09 '16 at 01:19
  • @Nikk I know what you want, but that is not possible with an executor service, unless you're fine with calling ```shutdownNow()```. Terminating a thread, is not a good idea. It's not a reliable mechanic. That's one of the reasons the ```stop``` method on ```Thread``` is deprecated. You should delegate the termination to the task itself, so it can implement logic to shut itself down in the appropriate way. – Jorn Vernee Jul 09 '16 at 01:31
  • I see. So what technique then is used in Java to prevent a program from indefinetly waiting for a resource to be available? – nikk Jul 09 '16 at 02:41
  • @nikk Best case is, you attach a listener that gets fired as soon as the resource is available. Other than that, most resources have a way to check if they are available (e.g. ```Future.isDone()```). You would poll that check in a while loop, where the while loop condition is a boolean that you can set from another thread, to stop the while loop and cancel execution of the task. – Jorn Vernee Jul 09 '16 at 11:07
  • But that's the point -- I don't want to wait indefinitely for resource to become available, for example, using while loops. I want the wait to expire after say, 5 seconds. Can please you give a code example that explain what you mean? – nikk Jul 09 '16 at 17:04
  • In a word, you cannot time a submit. Timing synchronous requests is something the service must handle itself and this service doesn't handle it. – edharned Jul 09 '16 at 22:10
  • 1
    But if resource.isAvailable() is "Blocking" from hardware side (and it is), then the thread will never return from waiting. – nikk Jul 10 '16 at 02:58
  • @nikk Yes, I was afraid of that, there's nothing you can really do in that case. You could launch another thread and use ```Thread.stop``` any ways. But that kind of means having to make your own executor service. What is the resource you're using? Someone might know an alternative. – Jorn Vernee Jul 10 '16 at 09:41
  • Right. Which is why I originally went with the option of using an executor service (as I illustrated above) -- and to then **force** the thread to `stop()` after an x amount of time. I think your earlier answer was very close to the solution. – nikk Jul 10 '16 at 17:18