Java:在不冻结的情况下调用自调用方法?

Java:在不冻结的情况下调用自调用方法?,java,swing,concurrency,Java,Swing,Concurrency,所以这真的很复杂,我花了一段时间才意识到到底发生了什么。希望你比我更了解它 我有一个显示GUI的Swing类。在GUI中我有一个按钮,在Swing类中我有一个方法,每当我单击按钮时都会调用该方法 当调用该方法时,我调用名为“Manager”的对象中的另一个方法。然后,manager中的方法调用名为“Core”的类中的另一个方法。Core中的方法设置一个局部变量,然后调用Core中另一个自调用的方法 问题是,由于它是自动参与的,所以它从不停止运行,对吗?由于它从未停止运行,所以不会向Core中的第

所以这真的很复杂,我花了一段时间才意识到到底发生了什么。希望你比我更了解它

我有一个显示GUI的Swing类。在GUI中我有一个按钮,在Swing类中我有一个方法,每当我单击按钮时都会调用该方法

当调用该方法时,我调用名为“Manager”的对象中的另一个方法。然后,manager中的方法调用名为“Core”的类中的另一个方法。Core中的方法设置一个局部变量,然后调用Core中另一个自调用的方法

问题是,由于它是自动参与的,所以它从不停止运行,对吗?由于它从未停止运行,所以不会向Core中的第一个方法返回任何内容。由于没有向该方法返回任何内容,所以也没有向Manager返回任何内容。由于该方法从未被调用,GUI类从未得到响应,这使得GUI处于冻结状态

非常抱歉描述得这么混乱。很遗憾,我不能发布代码。我希望任何人都能理解我的观点,一定有人以前也有过同样的问题

谢谢

编辑:


我忘了提到核心类是线程。

我不明白为什么必须自调用方法

你想做一些递归吗

如果这个方法永远不会结束,你会得到一个无限循环,这是不好的


根据您的尝试,您可以使用Java线程,或者重新考虑您的代码。。我打赌你做错了什么。

你有很多问题

1) 递归函数需要一个退出条件。大概是

public int imRecursive(int arg) {
   if (arg > 100) return;
   imRecursive(arg++);    
}
在该示例中,
imRecursive
不会被反复调用,一旦
arg
达到100,它就会停止


2) 对于swing应用程序,只有GUI相关的代码才能在主事件调度线程中运行。如果递归方法运行时间较长,您应该在另一个线程中使用,这样您的GUI就不会被锁定。

您需要分析您的自调用方法调用-这是一个递归调用-但是每个递归方法都必须有一些停止递归的条件-检查在您的情况下,您应该在什么条件下获得这样的条件

您的长期运行过程是什么阻止主Swing线程(EDT或事件调度线程)继续,这将使GUI完全无响应。解决方案是在后台线程中执行任何长时间运行的进程,例如由SwingWorker对象创建的进程。请查看名为的链接以了解有关SwingWorker对象使用的更多信息。

自调用称为递归。这是一种强大的技术,但如果不小心,可能会导致无限循环(挂起)。您需要确保每个递归(即每次方法调用自身时)都会朝着终止状态发生变化。例如,您可以有一个保证减少每次递归的数字,并且有一个退出条件,即您的数字为负数。另一个例子是,递归地“吃掉”一些数据结构,比如说一个字符串,直到什么都没有了。通常,这个“向终止状态改变的东西”作为参数传递给方法。递归方法应该以检查开始:我的参数是否处于终止状态?如果是,终止,如果不是,施展魔法


其次,对于Swing,您应该小心不要违反它的体系结构。它不是真正的MVC,而是一个2层框架。如果您对如何使用Swing感兴趣,我建议您阅读MVC等设计模式。

发布一些代码。你说核心是一个线程,我假设这意味着
类核心扩展线程
,但我们需要看看你在哪里生成一个新线程(在扩展线程的类中调用方法不会使它在单独的线程中运行)

如果递归(自调用)方法从未中断递归,那么很快就会导致
StackOverflowerError
。如果你没有得到,那么要么你没有使用递归函数,要么在某个地方破坏了递归。编写永不终止的方法的正确方法不是递归,而是迭代


GUI冻结几乎可以肯定是因为GUI线程中正在进行一些耗时的处理,这是另一个让人相信Core中的方法没有在单独的线程中运行的原因。

“自调用”听起来像是在执行递归,而这听起来不像实际发生的事情(假设您没有说您收到了内存不足错误)。您需要查找线程,因为它们的使用将解决您的问题。如果没有更具体的示例,很难准确地指出错误所在;在这方面,代码示例将非常有帮助(应该可以充分匿名/删除)。对不起,我忘了提到核心类实际上是一个线程。我不明白为什么它需要一个退出条件?它应该永远运行,这就是它自我信息的意义。我有一段时间(真的)以前循环过,但我只是改变了它,因为它对我做的事情更有效。@qwerty,然后试着让它成为一个SwingWorker,我在“今晚我做完了”的回答中链接到了它(现在真的很晚了),但我明天一定会尝试一下!你能给我一个非常简短的解释,说明SwingWorker和线程之间的区别吗?它们不是有相同的目的,在后台完成所有繁重的工作而不挂GUI吗?我正在使用线程。而且它应该是永无止境的,因为它总是有工作要做。它不是“您不能在与GUI相同的线程上运行,所以这不是问题。@querty:是的。不管您是否注意使用线程,您都在冻结程序的EDT。如果您需要我们进一步帮助,我认为您需要向我们提供更多信息,也许还需要一个最小的可运行可编译测试程序。”。