虽然我知道问起来有点傻,但我还是想多问问它的技术角度。
一个简单的无限循环示例:
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");
}
}
}
我怎样才能从这个类的外部中断(停止)这个无限循环(例如,在继承的帮助下)?
写到这里我都觉得很脏,但是...
从不同的线程,你可以调用System.setOut()
一个PrintStream
实现,RuntimeException
当你调用println()
.
我们可以使用变量来实现它volatile
,我们将改变它Thread
并停止循环。
for(;!cancelled;) /*or while(!cancelled)*/{
System.out.println("Stackoverflow");
}
这是编写无限循环的更好方法。
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;
}
}
您可以从另一个线程获取运行无限循环的线程并在其上调用中断。不过,您必须非常确定自己在做什么,并希望被中断的线程在中断时能够正常运行。
在这里,我用有问题的循环命名了线程,以便于识别。请注意,以下解决方案容易受到竞争条件的影响。
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();
}
}
请注意,在我的示例中,我假设两个线程在同一个 ThreadGroup 中。不能保证会出现这种情况,因此您可能需要遍历更多组。
如果您对此有一些控制权,那么这里的一个不错的模式是while(!isInterrupted())
在循环声明中使用t.interrupt()
而不是使用t.stop()
.
我给你的唯一建议是,即使在发布后,也不要这样做。你可以这样做,但你真的不应该。
我认为这是不可能的。仅在循环内使用break 。你可以使用
while(cond) {}
并从其他地方使它成为假
您可以通过从 Thread.currentThread() 询问来保持其对这个线程 [main] 的继承引用的静态引用来中断这个线程,就像这样
public class LoopInfinite{
public static Thread main = null;
public static void main(String[] args){
main = Thread.currentThread();
for(;;)
System.out.println("Stackoverflow");
}
}
要终止,您可以从其他线程调用它
LoopInfinite.main.interrupt();
但它只有在两个线程都属于同一组时才有效。否则调用线程会得到SecurityException
你的问题看起来像一个线程问题。但是,即使在线程中包含停止标志,现在也是一个好习惯
你不能从这个类之外阻止它。如果您使用继承,您可以覆盖您的循环,但如果没有 abort-flag,您将无法这样做。
非常开放的问题,但停止这样的循环很可能需要您从另一个线程进行操作。然后另一个线程需要设置一些你的无限循环可以定期检查的变量,如果该变量具有某个值;跳出循环。
如果不完全停止该过程,您将无法中断此特定循环。通常,如果您尝试从外部源执行此操作(我假设您无法控制源代码,因为如果您这样做了,您可以轻松地在循环中设置一个条件,例如您可以设置的布尔值从外部线程),您将不得不停止正在运行的线程,无论您是通过Thread 对象执行此操作(您必须以某种方式找到对它的引用,例如通过循环通过现有的 Threads),或者您是否停止它作为系统进程。
另一种选择是使用不是无限循环的循环覆盖该方法,但不幸的是,这不适用于您的示例,因为它是一个静态方法。
如果你需要一个“无限”循环,你肯定需要一个线程(否则你的应用程序将被卡住直到循环结束)。
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();
因此,这是一种让后台运行循环的简单方法。
添加一个变量 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;
}
}
}
这是我所做的:
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;
}
}