Java 如何中断无限循环
虽然我知道这样问有点傻,但我还是想问更多关于它的技术观点 无限循环的一个简单示例:Java 如何中断无限循环,java,loops,infinite-loop,Java,Loops,Infinite Loop,虽然我知道这样问有点傻,但我还是想问更多关于它的技术观点 无限循环的一个简单示例: public class LoopInfinite { public static void main(String[] args) { for (;;) { System.out.println("Stack Overflow"); } } } 如何从类外部中断(停止)这个无限循环(例如,借助继承)?您不能从类外部停止它。如果使用继承,则
public class LoopInfinite {
public static void main(String[] args) {
for (;;) {
System.out.println("Stack Overflow");
}
}
}
如何从类外部中断(停止)这个无限循环(例如,借助继承)?您不能从类外部停止它。如果使用继承,则可以覆盖循环,但如果没有中止标志,则无法覆盖循环。我认为这是不可能的。仅在循环中使用break。你可以用
while(cond) {}
从另一个地方将其设置为false是一个非常开放的问题,但停止这样的循环很可能需要从另一个线程进行操作。然后,另一个线程需要设置一些变量,您的无限循环可以定期检查这些变量,以及该变量是否具有特定值;打破循环。如果不完全停止流程,您将无法中断此特定循环。一般来说,如果您试图从外部源代码执行此操作(我假设您无法控制源代码,因为如果执行此操作,您可以轻松地在循环中设置一个条件,例如可以从外部线程设置的布尔值),那么无论您是通过(您必须以某种方式找到对它的引用,例如通过循环),或者是否将其作为一个对象停止
for(;!cancelled;) /*or while(!cancelled)*/{
System.out.println("Stackoverflow");
}
class BigLoop extends Thread
{
private boolean _sexyAndAlive = true;
// make some constructor !
public void softTerminate()
{
_sexyAndAlive = false;
}
public void run()
{
try
{
while( _sexyAndAlive )
{
// Put your code here
}
}
catch( Some Exceptions ... )
{
// ...
}
// put some ending code here if needed
}
}
// in another file :
BigLoop worker = new BigLoop();
worker.start(); // starts the thread
// when you want to stop it softly
worker.softTerminate();
另一种选择是使用一个不是无限循环的循环来覆盖该方法,但不幸的是,这不适用于您的示例,因为它是一个静态方法。您的问题看起来像是一个线程问题。但是,现在,即使在线程中包含停止标志也是一种很好的做法。我们可以使用
for(;!cancelled;) /*or while(!cancelled)*/{
System.out.println("Stackoverflow");
}
class BigLoop extends Thread
{
private boolean _sexyAndAlive = true;
// make some constructor !
public void softTerminate()
{
_sexyAndAlive = false;
}
public void run()
{
try
{
while( _sexyAndAlive )
{
// Put your code here
}
}
catch( Some Exceptions ... )
{
// ...
}
// put some ending code here if needed
}
}
// in another file :
BigLoop worker = new BigLoop();
worker.start(); // starts the thread
// when you want to stop it softly
worker.softTerminate();
这是编写无限循环的更好方法
public class LoopInfinite{
private static volatile boolean cancelled=false;
public static void main(String[] args){
for(;!cancelled;) { //or while(!cancelled)
System.out.println("Stackoverflow");
}
}
public void cancel(){
cancelled=true;
}
}
写这封信我都觉得很脏,但是 从另一个线程,您可以使用
PrintStream
实现调用System.setOut()
,当您调用println()时,它会抛出RuntimeException
您可以从另一个线程获取运行无限循环的线程,并对其调用中断。不过,您必须非常确定自己在做什么,并希望被中断的线程在被中断时能够正常运行
在这里,为了便于识别,我将线程命名为有问题的循环
Thread loop = new Thread() {
public void run() {
Thread.currentThread().setName("loop");
while(true) {
System.out.print(".");
}
}
}.start();
然后在另一节课上:
ThreadGroup group = Thread.currentThread().getThreadGroup();
Thread[] threads = new Thread[group.activeCount()];
group.enumerate(threads);
for(Thread t : threads) {
if(t.getName().equals("loop")) {
/* Thread.stop() is a horrible thing to use.
Use Thread.interrupt() instead if you have
any control over the running thread */
t.stop();
}
}
请注意,在我的示例中,我假设两个线程在同一个线程组中。不能保证会出现这种情况,因此您可能需要遍历更多的组
如果您对此有一些控制,这里的一个好模式是在循环声明中使用while(!isInterrupted())
,并使用t.interrupt()
而不是t.stop()
我给你的唯一建议是,即使在发布了这篇文章之后,也不要这样做。你可以这样做,但是你真的不应该添加一个变量shouldBreak或者可以使用getter和setter设置的东西
public class LoopInfinite {
private boolean shouldBreak = false;
public boolean isShouldBreak() {
return shouldBreak;
}
public void setShouldBreak(boolean shouldBreak) {
this.shouldBreak = shouldBreak;
}
public static void main(String[] args) {
// Below code is just to simulate how it can be done from out side of
// the class
LoopInfinite infinite = new LoopInfinite();
infinite.setShouldBreak(true);
for (;;) {
System.out.println("Stackoverflow");
if (infinite.shouldBreak)
break;
}
}
}如果你需要一个“无限”循环,你肯定需要一个线程(否则你的应用程序将被卡住,直到循环结束)
因此,这是一种让后台运行循环的简单方法。您可以通过请求thread.currentThread()来保持对该线程[main]的继承引用的静态引用来中断该线程,如下所示
公共类循环无限{
公共静态线程main=null;
公共静态void main(字符串[]args){
main=Thread.currentThread();
对于(;;)
System.out.println(“Stackoverflow”);
}
}
要终止,您可以从其他线程调用它
LoopInfinite.main.interrupt();
但只有当两个线程都是同一组的一部分时,它才会工作。否则调用线程将得到
while(Exit == false){
Scanner input = new Scanner(System.in);
String in = input.next();
switch(in){
case "FindH":
FindHyp hyp = new FindHyp();
float output = hyp.findhyp();
System.out.println(output);
case "Exit":
Exit = true;
break;
}
}
在这种情况下,你不能使用继承,因为它是一个静态方法。我的意思是,在一个简单的类中,这个无限循环代码是被编写的,那么我可以用什么方式停止这个无限函数呢?别忘了将cancelled声明为volatileMaybe,你可能想要
cancel()
方法也是静态的
。那么你不需要LoopInfinite
的对象就可以停止循环。@maba-dude u r r8在此上下文中。这是一个片段,不是实际实现。实际实现可能需要数千个更改。@Buhb:除非你有其他内存,否则没有必要这样做ng从多个线程读取/写入必须与“取消”标志一致。如果这是您的情况,最好使用锁/监视器或其他重量级并发控制,因为“volatile”本身可能不会帮助您。如果您正确使用锁,volatile在大多数情况下都是不必要的案例。除非您真正了解自己在做什么,直到CLR内存模型的级别以及存储/释放重新排序是什么,否则请避免使用它。只需使用锁。为什么要为此使用任何局部变量,而不是本机中断()-支持?只需编写,而(!isInterrupted())
将继续,直到有人调用中断()为止-为了简单起见,我不使用main();在一个简单的类中,只编写了这段无限代码,…然后,如果您无法更改代码,您必须找到它运行的线程,这可以通过创建时对它进行引用,也可以循环遍历所有线程,并尝试确定哪一个是合适的线程,但这可能是错误的困难。如果您更清楚地指定具体情况(循环是如何启动的,您需要发生什么,等等,例如,循环是由您控制的代码启动的?System.setOut(null)
就足够了。@MarkoTopolnik可能是另一个具有<