在线程中停止无限循环

4
    Thread d = new Thread(new Runnable() {
        @Override
        public void run() {
            while(true);
        }
    });
    d.start();

如何退出无限循环,不修改public void run()方法中的代码,且不使用d.stop();(已弃用的方法)。

附注:我宁愿公开我需要完成的整个练习详情。这是我需要处理的事情。他们给了我一个有时会进入无限循环的函数,我不能修改该方法。


2
你不能这样做。除非线程自己配合,否则无法停止一个Thread - Boris the Spider
1
你不能这样做。stop() 方法被废弃有原因的。 - SLaks
3
这是一个理论问题吗?System.exit(0) - Matt Ball
4
为什么你需要这样做?这是一种“代码高尔夫”吗?还是一道面试题? - thegrinner
1
按下重置按钮可能有点过头,但可以解决问题。 - JensG
显示剩余2条评论
5个回答

9
如何在不更改公共void run()方法内部代码的情况下退出无限循环,而且不能使用已过时的d.stop()方法(违反设计原则)?
我猜这是某种学术或面试题。如果您不能更改线程代码,则无法添加中断或易失性布尔检查。也不能调用.stop()(顺便说一句,这是一个过时的方法,从未是一个好主意)。
我所能想到的唯一方法是将线程设置为守护线程。
Thread d = new Thread(new Runnable() { ... });
...
d.setDaemon(true);
d.start();

在启动之前,它需要设置为守护进程。虽然这是一种Hack方法,但可能符合问题的框架。如果最后一个非守护线程退出,则JVM将终止该线程,这不会立即杀死该线程。

当然,您也可以删除 .start() 行,但这似乎超出了问题的范围。正如@MattBall指出的那样,System.exit(0); 也会关闭JVM,但这似乎也有些欺骗性。


如果线程内的代码是一个第三方API调用,可能会无限期挂起怎么办?例如Kafka中使用的consumer.poll()在旧版本中可能会挂起。这种情况下是否适用此解决方案? - user2206366
即使守护线程在 Kafka 调用内部被阻塞,它也会停止。话虽如此,Kafka 可能有一些后台线程不会受到影响。@user2206366 - Gray

5

除了杀死运行线程的JVM之外,我不知道你如何退出循环。

更好的方法至少应该检查线程中断:

Thread d = new Thread(new Runnable() {
   @Override
   public void run() {
      while(!Thread.currentThread().isInterrupted());
};
d.start();
d.interrupt();

1
楼主特别提到他不能在帖子里更改代码。 - Gray

3
你无法异步停止一个线程,唯一的方法是使用 stop() 方法。但如果没有这个方法,你就不能停止它。

2

如果没有使用.stop()方法,你需要在线程本身中更改代码。可以在这里查看一些想法。


1
这是正确的,但他也说他不想使用 stop,这是唯一的其他方法。我只是想提供一个信息来源和原因,让他能够向某人证明更改线程代码的合理性。 - Paul Harris

-1

永远避免使用 while(true)。尝试使用 while(running)。该条件应确定循环的生命周期。然后当你设置 running = false 时,循环的生命周期结束,随之线程也结束。


3
我该如何跳出无限循环,不改动方法public void run()内的代码? - Alexis C.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接