Behavior of future.get with 0 timeout - java

Can anyone point me to some documentation that makes clear that a 'Future.get` with a timeout of 0 will not wait?
The API docs for java.util.concurrent.Future does not make explicit the behavior of future.get(0, unit). Standing on its own, the statement "Waits if necessary for at most the given time..." implies this invocation will not wait at all, but given the long-standing behavior of Object.wait(0) (infinite wait), I'm nervous to depend on a "no wait" behavior of future.get(0, unit)
Scanning the source of some JDK-provided classes (viz. FutureTask) I see that this particular implementation of Future does not wait when the timeout is 0.
I'd like to be able to say
long timeout = Math.max(until - now, 0);
return future.get(timeout, TimeUnit.MILLISECONDS);
but I'm nervous about a Future implementing that as an infinite wait, so instead, I've explicitly coded it the way I would expect it to work:
long timeout = Math.max(until - now, 0);
if(timeout > 0 || future.isDone()){
return future.get(timeout, TimeUnit.MILLISECONDS);
} else {
throw TimeoutException();
}

Waits if necessary for at most the given timeā€¦
Waiting for at most zero time units is not waiting at all. That's not an implicit hint, it's an explicit guarantee.

Can anyone point me to some documentation that makes clear that a 'Future.get` with a timeout of 0 will not wait?
I can point you at some code if that helps. Looking into java.util.concurrent.FutureTask and then on to AbstractQueuedSynchronizer I see the following loop which I've pared down to show the relavent bits:
private boolean doAcquireSharedNanos(int arg, long nanosTimeout) {
long lastTime = System.nanoTime();
for (;;) {
...
if (nanosTimeout <= 0) {
cancelAcquire(node);
return false;
}
long now = System.nanoTime();
nanosTimeout -= now - lastTime;
}
This means that if nanosTimeout is 0 (which it will be if you pass in 0 to get) then it will try to acquire the future once and then timeout and return false.
If it makes you feel any better, you can set your timeout to be 1 nanosecond.

Related

Is there some neat way to make Threads (in Java) wait for theoretical time units as opposed to using Thread.sleep()?

Currently working on a university assessment, so I won't share specifics and I'm not asking for any explanation that will help me solve the main problem. I've already solved the problem, but my solution might be considered a little messy.
Basically, we're working with concurrency and semaphores. There is some shared resource that up to X (where X > 1) number of threads can access at a time and an algorithm which makes it a little more complicated than just acquiring and releasing access. Threads come at a certain time, use the resource for a certain time and then leave. We are to assume that no time is wasted when arriving, accessing, releasing and leaving the resource. The goal is to demonstrate that the algorithm we have written works by outputting the times a thread arrives, accesses the resource and leaves for each thread.
I'm using a semaphore with X number of permits to govern access. And it's all working fine, but I think the way I arrive at the expected output might be a bit janky. Here's something like what I have currently:
#Override
public void run() {
long alive = System.currentTimeMillis();
try { Thread.sleep(arrivalTime * 1000); }
catch (InterruptedException e) {} // no interrupts implemented
long actualArriveTime = System.currentTimeMillis() - alive;
boolean accessed = false;
while (!accessed) accessed = tryAcquire();
long actualAccessTime = System.currentTimeMillis() - alive;
try { Thread.sleep(useTime * 1000); }
catch (InterruptedException e) {} // no interrupts implemented
release();
long actualDepartTime = System.currentTimeMillis() - alive;
System.out.println(actualArriveTime);
System.out.println(actualAccessTime);
System.out.println(actualDepartTime);
}
I do it this way because where the expected output might be:
Thread Arrival Access Departure
A 0 0 3
B 0 0 5
C 2 2 6
... ... ... ...
My output looks something like:
Thread Arrival Access Departure
A 0 0 3006
B 0 0 5008
C 2 2 6012
... ... ... ...
I'm essentially making the time period much larger so that if the computer takes a fews milliseconds to acquire(), for example, it doesn't affect the number much. Then I can round to the nearest second to get the expected output. My algorithm works, but there are issues with this. A: It's slow; B: With enough threads, the milliseconds of delay may build so that I round to the wrong number.
I need something more like this:
public static void main(String[] args) {
int clock = 0;
while (threadsWaiting) {
clock++;
}
}
#Override
public void run() {
Thread.waitUntil(clock == arrivalTime);
boolean accessed = false;
while (!accessed) accessed = tryAcquire();
int accessTime = clock;
int depatureTime = accessTime + useTime;
Thread.waitUntil(clock == departureTime);
release();
System.out.println(arrivalTime);
System.out.println(accessTime);
System.out.println(departureTime);
}
Hopefully that's clear. Any help is appreciated.
Thanks!

overload in step find element

I have selenium java code testing some site in ff 41 and selenium 2.48. Last step of my code is findElement (timeout 30 sec). I don't have any error and my test does not fail. But I see overload in this step, its duration is 88 - 150 sec.
Any idea why my test does not fail after 30 sec?
Here is my last step code
errorMessage = "";
boolean flag23 = false;
for (int k = 0; k < 30; k++)
{
try
{
List<WebElement> element23 = findElements("print-confirmation");// "//a[#class='print-confirmation']");
if (element23.size() != 0)
{
flag23 = true;
break;
}
}
catch (Exception e)
{
pause(1000);
}
}
assertTrue(flag23); // new WebDriverWait(driver,
// 30).until(ExpectedConditions.presenceOfElementLocated(By.id("//a[#class='print-confirmation']")));
writer.append("\ntest89028:23 OK " + getRunTime(System.currentTimeMillis() - startTime));
startTime = System.currentTimeMillis();
If I get it right, you call findElements 30 times and you pause 1s after each iteration if you do not find your element yet. So you need worst case 30s only for pausing, plus time for the whole loop and especially for findElements. So your recorded time is more than 30s, since you record the whole code block execution. I don't know if I got it right and this might help you.
I'm not sure what is in the findElements() function... maybe a wait or sleep? Something in there is likely magnifying the wait time or you have an implicitWait() set. I would rewrite this block of code like this... (and remove any implicitWait()).
boolean flag23 = false;
try
{
new WebDriverWait(driver, 30).until(ExpectedConditions.presenceOfElementLocated(By.xpath("//a[#class='print-confirmation']")));
flag23 = true;
}
catch (TimeoutException e)
{
System.out.println("Element not found due to TimeoutException");
}
assertTrue(flag23);
I think it's easier to read and is more controlled. You should not mix implicit and explicit waits or you will get weird behaviors (likely similar to this).
http://www.seleniumhq.org/docs/04_webdriver_advanced.jsp#explicit-and-implicit-waits
WARNING: Do not mix implicit and explicit waits. Doing so can cause unpredictable wait times. For example setting an implicit wait of 10s and an explicit wait of 15 seconds, could cause a timeout to occur after 20 seconds.

How can I properly block a thread until timeout starts?

I would like to run several tasks in parallel until a certain amount of time has passed. Let us suppose those threads are CPU-heavy and/or may block indefinitely. After the timeout, the threads should be interrupted immediately, and the main thread should continue execution regardless of unfinished or still running tasks.
I've seen a lot of questions asking this, and the answers were always similar, often along the lines of "create thread pool for tasks, start it, join it on timeout"
The problem is between the "start" and "join" parts. As soon as the pool is allowed to run, it may grab CPU and the timeout will not even start until I get it back.
I have tried Executor.invokeAll, and found that it did not fully meet the requirements. Example:
long dt = System.nanoTime ();
ExecutorService pool = Executors.newFixedThreadPool (4);
List <Callable <String>> list = new ArrayList <> ();
for (int i = 0; i < 10; i++) {
list.add (new Callable <String> () {
#Override
public String call () throws Exception {
while (true) {
}
}
});
}
System.out.println ("Start at " + (System.nanoTime () - dt) / 1000000 + "ms");
try {
pool.invokeAll (list, 3000, TimeUnit.MILLISECONDS);
}
catch (InterruptedException e) {
}
System.out.println ("End at " + (System.nanoTime () - dt) / 1000000 + "ms");
Start at 1ms
End at 3028ms
This (27 ms delay) may not seem too bad, but an infinite loop is rather easy to break out of - the actual program experiences ten times more easily. My expectation is that a timeout request is met with very high accuracy even under heavy load (I'm thinking along the lines of a hardware interrupt, which should always work).
This is a major pain in my particular program, as it needs to heed certain timeouts rather accurately (for instance, around 100 ms, if possible better). However, starting the pool often takes as long as 400 ms until I get control back, pushing past the deadline.
I'm a bit confused why this problem is almost never mentioned. Most of the answers I have seen definitely suffer from this. I suppose it may be acceptable usually, but in my case it's not.
Is there a clean and tested way to go ahead with this issue?
Edited to add:
My program is involved with GC, even though not on a large scale. For testing purposes, I rewrote the above example and found that the results given are very inconsistent, but on average noticeably worse than before.
long dt = System.nanoTime ();
ExecutorService pool = Executors.newFixedThreadPool (40);
List <Callable <String>> list = new ArrayList <> ();
for (int i = 0; i < 10; i++) {
list.add (new Callable <String> () {
#Override
public String call () throws Exception {
String s = "";
while (true) {
s += Long.toString (System.nanoTime ());
if (s.length () > 1000000) {
s = "";
}
}
}
});
}
System.out.println ("Start at " + (System.nanoTime () - dt) / 1000000 + "ms");
try {
pool.invokeAll (list, 1000, TimeUnit.MILLISECONDS);
}
catch (InterruptedException e) {
}
System.out.println ("End at " + (System.nanoTime () - dt) / 1000000 + "ms");
Start at 1ms
End at 1189ms
invokeAll should work just fine. However, it is vital that you write your tasks to properly respond to interrupts. When catching InterruptedException, they should exit immediately. If your code is catching IOException, each such catch-block should be preceded with something like:
} catch (InterruptedIOException e) {
logger.log(Level.FINE, "Interrupted; exiting", e);
return;
}
If you are using Channels, you will want to handle ClosedByInterruptException the same way.
If you perform time-consuming operations that don't catch the above exceptions, you need to check Thread.interrupted() periodically. Obviously, checking more often is better, though there will be a point of diminishing returns. (Meaning, checking it after every single statement in your task probably isn't useful.)
if (Thread.interrupted()) {
logger.fine("Interrupted; exiting");
return;
}
In your example code, your Callable is not checking the interrupt status at all, so my guess is that it never exits. An interrupt does not actually stop a thread; it just signals the thread that it should terminate itself on its own terms.
Using the VM option -XX:+PrintGCDetails, I found that the GC runs more rarely, but with a far larger time delay than expected. That delay just so happens to coincide with the spikes I experienced.
A mundane and sad explanation for the observed behavior.

Java: How to distinguish between spurious wakeup and timeout in wait()

Here is a case where a thread is waiting for notify() or a timeout. Here a while loop is added to handle spurious wake up.
boolean dosleep = true;
while (dosleep){
try {
wait(2000);
/**
* Write some code here so that
* if it is spurious wakeup, go back and sleep.
* or if it is timeout, get out of the loop.
*/
} catch (InterruptedException e) {
e.printStackTrace();
}
}
In this case how can I distinguish between a spurious wake up and time out? If it is a spurious wake up, i need to go back and wait. And if it is a timeout, i need to get out of the loop.
I can easily identify the case of notify(), because i will be setting the dosleep variable to false while notify() call.
EDIT: i am using 1.4 java version, due to embedded project requirement. I cannot use Condition as it is available only post 1.5.
Thanks in advance.
You could do this:
boolean dosleep = true;
long endTime = System.currentTimeMillis() + 2000;
while (dosleep) {
try {
long sleepTime = endTime - System.currentTimeMillis();
if (sleepTime <= 0) {
dosleep = false;
} else {
wait(sleepTime);
}
} catch ...
}
That should work fine in Java 1.4, and it will ensure that your thread sleeps for at least 2000ms.
You need to keep track of your timeout if you want to distinguish the two cases.
long timeout = 2000;
long timeoutExpires = System.currentTimeMillis() + timeout;
while(dosleep) {
wait(timeout);
if(System.currentTimeMillis() >= timeoutExpires) {
// Get out of loop
break;
}
}
That said, denis's recommendation of using the Condition class is the better way to do this.
I believe Locks and Condition will better fit your need in this case. Please check the javadocs for Condition.awaitUntil() - it has an example of usage

Unstable speed of gameloop

I'm making a simple breakout game in OpenGL(-es) on Android. Initially I had the updating of the game's state and the drawing calls in the same loop: onDrawFrame. Now I decided to split up the two, only leaving the rendering calls in onDrawFrame, and the gamestate was managed in another Thread:
public void run() {
Log.d("GameLogicThread", "GameLogicThread started");
final long UPDATE_INTERVAL = 1000000000 / 30;
long endingTime;
int timeElapsed;
long startingTime = System.nanoTime();
while (!running) {// wait for it...
}
while (running) {
endingTime = System.nanoTime();
timeElapsed = (int) (endingTime - startingTime);
Log.d("timeElapsed",Integer.toString(timeElapsed));
if (timeElapsed < UPDATE_INTERVAL-timeElapsed){
try {
Thread.sleep(timeElapsed);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
startingTime = System.nanoTime();
Game.updateGame(timeElapsed);
}
EDIT
I now have changed the code like this ^^, but it still doesn't work correctly..
Is it something in the loop itself that's wrong, or should I look outside (Probably not, since it worked great before moving the code). What should I do?
There are a few logical errors which are pointed out/discussed in the comments below:
endingTime = System.currentTimeMillis();
timeElapsed = (int) (endingTime - startingTime);
// Why is the "elapsed" time being waited? Hmm.
// If *any* wait is being done (I'd recommend sleep(0) for starters)
// it should be the MAXIMUM desired cycle time MINUS the
// currently used cycle time (MINUS some fudge factor).
if (timeElapsed < UPDATE_INTERVAL) // I dislike hanging blocks...
try {
Thread.sleep(timeElapsed);
} catch (InterruptedException e) {
e.printStackTrace();
}
startingTime = System.currentTimeMillis();
// The game needs to know the TOTAL time elapsed since
// the last update, not the time "until before the yield".
// This will likely be passed fictitiously small values as
// it is only time the the LAST updateGame took to run.
Game.updateGame(timeElapsed);
I would never expect to see timeElapsed (passed to updateGame) below say 10ms with sleep(...) and the corrected time calculations.
However, it may not have the required precision (increasing the minimum cycle length to say 1/30 sec, which would result from the fixed math, would make this less important): see Cristian Vrabie's answer for a suggestion on a higher-resolution timer. (There may be some better 3rd-party alternatives designed just for this -- there is in "normal" Java -- I don't program Android ;-)
Happy coding.
The loop doesn't look broken to me. The move to separate threads is definitely a good one or you would have serious problems when the rendering of a frame takes too long.
Have you tried to use nanoTime() for more accuracy?

Categories

Resources