Java中的可变深度递归
由于我正在上并发课程并学习 Java 的线程机制,所以我正在做一个小实验,看看递归在 Java 语言中到底能走多远。现在我运行的是 Intel i5 四核处理器,主频为 2.8 GHz,内存为 4GB。我在 x64 的 Windows 7 上运行,并在带有标准 JRE 的 Eclipse 中运行?不确定最后一部分,我刚刚从 Sun 的网站下载了一些东西。
不管怎样,
public class StacksizeTest implements Runnable {
int depth = 0;
public void run()
{
try
{
doOverflow();
}
catch (StackOverflowError e)
{
System.out.print("Overflow ocurred at depth " + depth + ".\n");
}
}
void doOverflow()
{
depth += 1;
doOverflow();
}
public static void main(String argv[])
{
Thread mt = new Thread(new StacksizeTest());
mt.start();
mt.run();
}
}
我也使用默认的调用堆栈大小运行,根据设置文件,我很确定它是 512Mb。
因此,当我运行程序并启动一个新线程时,我不断获得可变深度,并且打印语句打印两次。我认为 print 语句是有意义的,因为它应该在新线程上运行 mt。我感到困惑的是,如果我排除 .start() 并只调用 .run() ,“深度”总是相同的(大约 11,500 左右),但是当我使用 .start() 时,我得到的深度可变。有几个是 22789、22330 和 22381。我很难理解这是为什么。有人可以阐明这个问题吗?
谢谢,
马特
So I'm doing a little experiment on exactly how far recursion can go in the Java language since I'm taking a class on concurrency and learning about Java's threading mechanisms. Right now I'm running a Intel i5 Quad-core with 2.8 GHz and 4GB of RAM. I'm running on Windows 7 with x64 and in Eclipse with the standard JRE? Not sure about that last part I just downloaded something from Sun's website.
Anyway,
public class StacksizeTest implements Runnable {
int depth = 0;
public void run()
{
try
{
doOverflow();
}
catch (StackOverflowError e)
{
System.out.print("Overflow ocurred at depth " + depth + ".\n");
}
}
void doOverflow()
{
depth += 1;
doOverflow();
}
public static void main(String argv[])
{
Thread mt = new Thread(new StacksizeTest());
mt.start();
mt.run();
}
}
I'm also running with the default call stack size, which im pretty sure is 512Mb according to the settings file.
So when I run the program and start a new thread I keep getting variable depths, as well as the print statement printing twice. The print statement makes sense I think because it should be running mt on a new thread. What I'm confused about is if I exclude .start() and just call .run() the "depth" is always the same (about 11,500 or so), but when I use .start() I'm getting variable depths. a couple have been 22789, 22330, and 22381. I'm having difficulty understanding why this is. Could someone possibly shed some light on this issue?
Thanks,
Matt
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
对
.start()
的调用将使用run()
启动一个新线程,然后您将调用run()< /code> 再次在主线程上。所以你有两个堆栈深度线程同时运行。由于您还有一个计算不受同步互斥体保护的深度的共享变量,因此您遇到了经典的变量争用问题。
为了不将该问题与变量争用混淆,我将限制自己运行堆栈深度检查器的一个实例。
The call to
.start()
will start a new thread withrun()
, then you're callingrun()
again on the main thread. So you've got two stack depth threads running at the same time. Since you've also got a shared variable counting the depth that's not protected by a synchronized mutex, you've got a classic variable contention problem.In order not to confuse the issue with variable contention, I would limit yourself to one running instance of the stack depth checker.
当您调用
start()
时,您将异步触发该方法,因此您将运行该方法两次,因为start()
最终会调用run( )
,此外您还自己调用run()
,因此您有两个线程递增您的深度
计数器。消除start()
,您会得到较小的计数,因为您只运行一个线程。编辑:我刚刚看到格雷格的回答。我更喜欢他的。
When you call
start()
you're firing off the method asynchronously, so you're running it twice becausestart()
eventually makes a call torun()
, and in addition you're callingrun()
yourself, so you've got two threads incrementing yourdepth
counter. Eliminate thestart()
, and you get your smaller count because you're only running a single thread.EDIT: I just saw Greg's answer. I like his more.