Output of the following code is 9123:9158
import java.util.concurrent.atomic.AtomicInteger;
public class StackOverflow {
private static AtomicInteger atomicInteger = new AtomicInteger(0);
private static int staticInt = 0;
public static void main(String args[]) {
int atomicInt = atomicInteger.incrementAndGet();
staticInt++;
try {
// recursive call to main() to get StackOverflowError
main(args);
} catch(StackOverflowError soe) {
System.out.println(atomicInt+":"+staticInt);
// staticInt gets more count, why so?
}
}
}
This produces a difference of 35 between static int
and AtomicInteger
. I am not sure why this behaves so and I have these questions I would like to get answers for.
While running on a single thread both should give same count right? Any idea why this is not behaving so?
How do we get the correct number of calls required for StackOverflowError
to occur?
Is it wrong to use AtomicInteger
in a static
contekt?
It's because you are printing atomicInt
. If you printed atomicInteger
instead you would get the expected result.
There is one atomicInt
variable per call to main
, so in your example there are 9000+ such variables.
When you get the StackOverflowError, the execution goes through the stack in reverse order until the System.out.println
statement can execute (it may throw a SOE too!), and the value of the atomicInt
corresponding to that specific main
invocation is smaller than the curent value of staticInt
or atomicInteger
.
In other words, in your example, 34 StackoverflowError are thrown and the 35th invocation of System.out.println
succeeds, but atomicInt
in that invocation of main
is 35 less than the current value of staticInt
, hence 9123 vs 9158.
To see it you can modify your program like so:
private static int soeCount = 0;
//...
} catch (StackOverflowError soe) {
soeCount++;
System.out.println(atomicInt + ":" + staticInt + " -> " + soeCount);
// staticInt gets more count, why so?
}
and you should see that soeCount
is larger than 1 (although not necessarily equal to the difference as soeCount++
may not be executed on each stack frame.
It seems that System.out.println(atomicInt+":"+staticInt);
is also causing a stack overflow. So you actually print the values of a few incarnations earlier.
staticInt
is a static field, so it has the max number of incarnations, while atomicInt
is a local variable in the incarnation of main
that actually succeeds in executing the println
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With