以下代码的输出为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?
}
}
}
这会在static int
和AtomicInteger
之间产生35的差异。我不确定为什么会这样,我有这些问题我想得到答案。
在单个线程上运行时,两者都应该给出相同的计数吗?知道为什么这不是这样吗?
我们如何获得StackOverflowError
所需的正确呼叫次数?
在AtomicInteger
contekt中使用static
是否错误?
答案 0 :(得分:9)
这是因为您正在打印atomicInt
。如果您打印atomicInteger
,则会获得预期结果。
每次调用atomicInt
时都会有一个main
变量,所以在您的示例中有9000多个这样的变量。
当你得到StackOverflowError时,执行以相反的顺序通过堆栈直到System.out.println
语句可以执行(它也可能抛出一个SOE!),并且atomicInt
的值对应于特定main
调用小于staticInt
或atomicInteger
的临界值。
换句话说,在您的示例中,抛出了34个StackoverflowError,并且System.out.println
的第35次调用成功,但atomicInt
调用中的main
比当前值小35 staticInt
,因此9123 vs 9158。
要查看它,您可以像这样修改您的程序:
private static int soeCount = 0;
//...
} catch (StackOverflowError soe) {
soeCount++;
System.out.println(atomicInt + ":" + staticInt + " -> " + soeCount);
// staticInt gets more count, why so?
}
你应该看到soeCount
大于1(虽然不一定等于差异,因为soeCount++
可能不会在每个堆栈帧上执行。
答案 1 :(得分:3)
似乎System.out.println(atomicInt+":"+staticInt);
也导致堆栈溢出。所以你实际上早先打印了一些化身的值。
staticInt
是一个静态字段,因此它具有最大化身数,而atomicInt
是main
的实体中实际成功执行{{1}的本地变量}}