Ideal value for timeout in ExecutorService - java

I want to understand about the ideal value of timeout in awaitTermination() method for executorservice. How should we decide the ideal timeout? Does it harm if we use one day as the timeout?
boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException;
suppose I am loading data from one database to another database. Sometimes it may slow down because of network issues and even the number of documents to upload may also increase. So it becomes a little difficult to judge the max time. So in that scenario, if I use one day as a timeout (Actually, I want to use awaitTermination() without a timeout from executorService side). What exactly are the disadvantages of this?
What is the downside of awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS)?
because anyways, executorservice will terminate once the tasks are done

This depends on how long a task can consume.
How long in the worst case you longest task will take?
Lets say it will take in worst case 1 min. Then take 2 min.
You simply calculate worst case time plus a buffer.
You simply don't wont that the started job is canceled without reason because you can get a data loss.
If you are working e.g. on a queue with confirmation and you confirm only if your job is done, you can terminate immediately because on next start and after timeout your worker gets the task again. (But be carefully. If you servere restarts you can end up in a loop)

Related

Should I have a dedicated thread for watching a timeout?

Right now I have two threads running in my program. One constantly tries to read input from the user, and the other watches for a timeout. A timeout occurs if the user does not send any input in a given amount of time. The two threads look like this:
User input thread
while(true){
if(in.hasNextLine()){
processLine(in.nextLine());
timeLastRecieved = System.currentTimeMillis();
}
}
Timeout thread
while(true){
//Check for a timout
if(timeLastRecieved+timeoutDuration <= System.currentTimeMillis())
timeUserOut();
else{
//Sleep until it is possible for a timeout to occur
Thread.sleep((timeLastSent+timeoutDuration) - System.currentTimeMillis());
}
}
As of now I have these thread separated, but I could combine them like this...
while(true){
if(in.hasNextLine()){
processLine(in.nextLine());
timeLastRecieved = System.currentTimeMillis();
}
//Check for a timout
if(timeLastRecieved+timeoutDuration <= System.currentTimeMillis())
timeUserOut();
}
But I really don't need to check for a timeout that frequently. So should I combine the threads and check for a timeout too often, or should I have two threads. I am not as worried about performance as I am proper coding etiquette. If it means anything the timeout duration in something like 15 minutes long.
EDIT: Just want to point out that in the version with two thread I am sleeping, but in the combined version I never sleep the thread. This obviously causes the if statement that checks for a timeout to run more then necessary.
To summarize my comments: I don't think a separate thread to check for timeouts is necessary.
Reasons:
You'd need to share information like timeLastRecieved between them, which could be more complex than wanted (e.g. AFAIK in some cases access to long values is not atomic).
From your description it seems that polling for user input and timeout (no input provided in time) are closely related, thus the polling thread could check for the timeout as well. That doesn't mean it has to handle the timeout too, just reporting it somewhere or calling some timeout handler might be better design.
It is easier to read and understand since updating timeLastRecieved and checking for a timeout is handled in the same place.
Since there is no inter-thread communication nor coordination needed (there are no threads that need to communicate) it probably is more robust as well.
A few hints on checking for the timeout:
You should calculate the timeout threshold when you update timeLastReceived and then only check agains the current time instead of calculating it in every iteration.
You might want to calculate the timeout threshold before processing the input in order not to have it depend on the processing time as well.
Finally, there are alternative approaches like using java.util.Timer. Here you could simply schedule a timeout task which is executed when the timeout should occur. That task then would check if the timeout really happened and if not it just returns.
To handle new input before the timeout occured you could use at least two approaches:
Cancel the current timeout task, remove it from the timer and schedule a new one.
If there is already a scheduled timeout task then don't schedule a new one but wait for the current one to run. The current one then checks for the timeout and if none happened it schedules a new task (or itself) for the current anticipated timeout (note that this would require some inter-thread communcation so be careful here).
You need to have two threads - one waiting for data coming in through the InputStream / Reader, and one that's watching the time to see if the time elapsed as taken too long. The only way to do it with 1 thread would be to sleep for a segment of the timeout period and then poll for data periodically. But that's less efficient than having a separate thread dedicated to reading from your InputStream/Reader.
You may want to check out Timeout as a generic option for implementing a timeout

Java ScheduledExecutorService behind the scenes

How does things like scheduleAtFixedRate work? How does it work behind the scenes and is there a penalty to using it?
More specifically, I have a task that I want to run periodically, say every 12 hours. The period is not strict at all, so my first instinct was to check in every request (tomcat server) if it's been more than >12 hours since the task last executed and if so, execute it and reset the timer. The downside of this is that I have to do a small time check on every request, make sure the task is run only once (using a semaphore or something similar) and the task might not execute in a long time if there's no requests.
scheduleAtFixedRate makes it easier to schedule a recurring task, but since I don't know how it does it, I don't know what the performance impact is. Is there a thread continually checking if the task is due to run? etc.
edit:
In Timer.java, there's a mainLoop function which, in my understanding, is something like this (overly simplified):
while(true) {
currentTime = System.currentTimeMillis();
if(myTask.nextExecutionTime == currentTime) myTask.run();
}
Won't this loop try to run as fast as possible and use a ton of CPU (I know, obviously not, but why)? There's no Thread.sleep in there to slow things down.
You can read the code if you wish to work out how it works.
There is an overhead using ScheduledExecutorService in terms of CPU and memory, however on the scale of hours, minutes, second even milli-seconds, it probably not work worrying about. If you have a task running in the range of micro-seconds, I would consider something more light weight.
In short, the overhead is probably too small for you to notice. The benefit it gives you is ease of use, and it is likely to be worth it.

Running thread for 2 millisecond and then wait for particular time before running it again

I have one method execute(data) which takes considerable time (depending on data like 10 seconds or 20 seconds), it has timeout feature which is 30 seconds default. I want to test that method. One way of doing it is to collect enough data which lasts more than 30 seconds and then see whether I get timeout exception. Other way of doing it is to use threads. What I intend to do is to run method for some milliseconds and then put thread on wait before I get timeout exception or make it last for some seconds.Can any one please suggest how can I achieve that.
You should walk through the Java Threads Tutorial (Concurrency). Any answer on Stack Overflow would need to be really long to help you here, and the Threads/Concurrency tutorials already cover this well.
http://docs.oracle.com/javase/tutorial/essential/concurrency/
You could use
Thread.sleep( millis );
to put the thread to sleep for the required time.
Or, you could put your data processing code into a loop, so that it processes it multiple times. This would recreate the scenario of the thread actually processing data for longer than 30 seconds.
Or, you could test your code with a shorter timeout value.

Return a method when time limit is up in - java

i just started to learn programming (2 weeks ago), and i am trying to make a bot for a game. In the main class of the bot, there are 3 methods that needs to be returned within 2second, or it will return null. I want to avoid returning null and return what it has calculate during 2sec instead.
public ArrayList<PlaceArmiesMove> getPlaceArmiesMoves(BotState state, Long timeOut){
ArrayList<PlaceArmiesMove> placeArmiesMoves = new ArrayList<PlaceArmiesMove>();
// caculations filling the ArrayList
return placeArmiesMoves;
}
what i want to do is after 2 second, returning placeArmiesMoves, wether the method finished running or not. I have read about guava SimpleTimeLimiter and callWithTimeout() but i am totally lost about how to use it (i read something about multithreading but i just don't understand what this is)
i would be incredibly grateful if someone could help me! thanks
Given a function like getPlaceArmiesMove, there are several techniques you might use to bound its execution time.
Trust the function to keep track of time itself
If the function runs a loop, it can check on every iteration whether the time has expired.
long startTime = System.currentTimeMillis()
for (;;) {
// do some work
long elapsed = System.currentTimeMillis() - startTime;
if (elapsed >= timeOut) {
break;
}
}
This technique is simple, but there is no guarantee it will complete before the timeout; it depends on the function and how granular you can make the work (of course, if it's too granular, you'll be spending more time testing if the timeout has expired than actually doing work).
Run the function in a thread, and ask it to stop
I'm not familiar with Guava, but this seems to be what SimpleTimeLimiter is doing. In Java, it isn't generally possible to forcibly stop a thread, though it is possible to ignore the thread after a timeout (the function will run to completion, but you've already used its partial result, and ignore the complete result that comes in too late). Guava says that it interrupts the thread if it has not returned before the timeout. This works only if your function is testing to see if it has been interrupted, much like the "trust your function" technique.
See this answer for an example on how to test if your thread has been interrupted. Note that some Java methods (like Thread.sleep) may throw InterruptedException if the thread is interrupted.
In the end, sprinkling checks for isInterrupted() all over your function won't be much different than sprinkling manual checks for the timeout. So running in a thread, you still must trust your function, but there may be nicer helpers available for that sort of thing (e.g. Guava).
Run the function in a separate process, and kill it
An example of how to do this is left as an exercise, but if you run your function in a separate process (or a thread in languages that support forcibly stopping threads, e.g. Erlang, Ruby, others), then you can use the operating system facilities to kill the process if it does not complete after a timeout.
Having that process return a partial result will be challenging. It could periodically send "work-in-progress" to the calling process over a pipe, or periodically save work to a file.
Use Java's Timer package , however this will require you to understand concepts such as threads and method overriding. Nevertheless, if this is what you require, the answer is quite similar to this question How to set a timer in java

Java execute task with a number of retries and a timeout

I'm trying to create a method that executes a given task in a maximum amount of time. If it fails to finish in that time, it should be retried a number of times before giving up. It should also wait a number of seconds between each try. Here's what I've come up with and I'd like some critiques on my approach. Is their a simpler way to do this using the ScheduledExecutorService or is my way of doing this suffice?
public static <T> T execute(Callable<T> task, int tries, int waitTimeSeconds, int timeout)
throws InterruptedException, TimeoutException, Exception {
Exception lastThrown = null;
for (int i = 0; i < tries; i++) {
try {
final Future<T> future = new FutureTask<T>(task);
return future.get(timeout, TimeUnit.SECONDS);
} catch (TimeoutException ex) {
lastThrown = ex;
} catch (ExecutionException ex) {
lastThrown = (Exception) ex.getCause();
}
Thread.sleep(TimeUnit.SECONDS.toMillis(waitTimeSeconds));
}
if (lastThrown == null) {
lastThrown = new TimeoutException("Reached max tries without being caused by some exception. " + task.getClass());
}
throw lastThrown;
}
I think, but it's my opinion, that if you are scheduling network related tasks, you should not retry but eventually run them in parallel. I describe this other approach later.
Regarding your code, you should pass the task to an executor, or the FutureTask to a thread. It will not spawn a thread or execute by itself. If you have an executor (see ExecutorService), you don't even need a FutureTask, you can simply schedule it and obtain a callable.
So, given that you have an ExecutorService, you can call :
Future<T> future = yourExecutor.submit(task);
Future.get(timeout) will wait for that timeout and eventually return with TimeoutException even if the task has never started at all, for example if the Executor is already busy doing other work and cannot find a free thread. So, you could end up trying 5 times and waiting for seconds without ever giving the task a chance to run. This may or may not be what you expect, but usually it is not. Maybe you should wait for it to start before giving it a timeout.
Also, you should explicitly cancel the Future even if it throws TimeoutException, otherwise it may keep running, since nor documentation nor code says it will stop when a get with timeout fails.
Even if you cancel it, unless the Callable has been "properly written", it could keep running for some time. Nothing you can do it about it in this part of code, just keep in mind that no thread can "really stop" what another thread is doing in Java, and for good reasons.
However I suppose your tasks will mostly be network related, so it should react correctly to a thread interruption.
I usually use a different strategy is situations like this:
I would write public static T execute(Callable task, int maxTries, int timeout), so the task, max number of tries (potentially 1), max total timeout ("I want an answer in max 10 seconds, no matter how many times you try, 10 seconds or nothing")
I start spawning the task, giving it to an executor, and then call future.get(timeout/tries)
If I receive a result, return it. If I receive an exception, will try again (see later)
If however i get a timeout, I DON'T cancel the future, instead I save it in a list.
I check if too much time has passed, or too many retries. In that case I cancel all the futures in the list and throw exception, return null, whatever
Otherwise, I cycle, schedule the task again (in parallel with the first one).
See point 2
If I have not received a result, I check the future(s) in the list, maybe one of the previous spawned task managed to do it.
Assuming your tasks can be executed more than once (as I suppose they are, otherwise no way to retry), for network stuff I found this solution to work better.
Suppose your network is actually very busy, you ask for a network connection, giving 20 retries 2 seconds each. Since your network is busy, none of the 20 retries manages to get the connection in 2 seconds. However, a single execution lasting 40 seconds may manage to connect and receive data. It's like a person pressing f5 compulsively on a page when the net is slow, it will not do any good, since every time the browser has to start from the beginning.
Instead, I keep the various futures running, the first one that manages to get the data will return a result and the others will be stopped. If the first one hangs, the second one will work, or the third one maybe.
Comparing with a browser, is like opening another tab and retrying to load the page there without closing the first one. If the net is slow, the second one will take some time, but not stopping the first one, which will eventually load properly. If instead the first tab was hung, the second one will load rapidly. Whichever loads first, we can close the other tab.
The thread on which your execute is called will block for so much time. Not sure if this is correct for you. Basically , for these types of tasks , ScheduledExecutorService is best.You can schedule a task and specify the timings. Take a look at ScheduledThreadPoolExecutor

Categories

Resources