【问题标题】:Java Main Class Thread does not terminate anymore using Java Multithreading in EclipseJava Main Class Thread 不再使用 Eclipse 中的 Java Multithreading 终止
【发布时间】:2018-12-05 22:28:06
【问题描述】:

我创建了自己的线程类来实现Runnable 接口。但是每次我开始将自己的线程类作为新线程运行时,主类线程不再自行终止。这只是 Eclipse 中的一个问题,还是我在服务器上运行它也会有问题?我是否必须更改调用线程的内容才能使 main 方法正确终止?


这是我的基本自制线程:

public class OwnThread implements Runnable {
   @Override
   public void run() {
      //do something
   }
} 

这是不再终止的主类:

public static void main(String[] args) {    
   Thread thread = new Thread(new OwnThread());
   thread.start();
}

当我调试它时,最后调用的方法是Thread-class 的exit()-method。看完这几行代码后,这个过程就永远继续下去了:

/**
 * This method is called by the system to give a Thread
 * a chance to clean up before it actually exits.
 */
private void exit() {
   if (group != null) {
      group.threadTerminated(this);
      group = null;
   }
   /* Aggressively null out all reference fields: see bug 4006245 */
   target = null;
   /* Speed the release of some of these resources */
   threadLocals = null;
   inheritableThreadLocals = null;
   inheritedAccessControlContext = null;
   blocker = null;
   uncaughtExceptionHandler = null;
}

这是永远运行的线程的屏幕截图。 TestInterface 类是 main 方法所在的位置:

【问题讨论】:

  • 除了“这不是正确的做法”:您是否尝试在main 末尾添加thread.join()?
  • 通常在运行exit() 方法时,线程被视为“终止”。在那之后你调试过线程的状态吗?
  • @daniu 我用join() 和yield() 尝试过,没有改变任何东西。但是,那么正确的方法是什么?
  • @DavidStuder 在您的示例中,没有线程(主线程和其他启动的线程)正在运行。该程序直接终止。也许你过于简化了你的代码。看看我的例子以获得一个想法。否则请发送minimal reproducible example。
  • 好的。这很奇怪。显然两个线程都已终止,但应用程序仍在运行。这可能是 Eclipse 的问题,但也可能是 Java VM 的问题。也许重新安装会有所帮助。 这不是正常行为,与您的 Java 代码无关。

标签: java multithreading


【解决方案1】:

这个问题确实不是多线程逻辑本身引起的,是Eclipse和各自的JVM引起的。在 Netbeans 或 Tomcat 8 服务器 上运行完全相同的代码不会导致任何问题。重新安装 Eclipse 并没有解决 Eclipse 框架内的故障,但确定该问题不会在服务器上造成任何问题就足以让我关闭此案例。

感谢Seelenvirtuose 的提示和他的努力。

【讨论】:

    【解决方案2】:

    但每次我开始将自己的线程类作为新线程运行时,主类线程不再自行终止。

    这有点不对。您的程序不会终止,因为至少存在一个仍在运行的非守护线程。规则是:如果所有非守护线程都终止,则 Java 程序终止。

    我修改了你的程序以明确这种行为:

    public class OwnThread implements Runnable {
        @Override
        public void run() {
            runForever();
        }
    
        public static void main(String[] args) {
            Thread thread = new Thread(new OwnThread());
            thread.start();
            runForever();
        }
    
        private static void runForever() {
            while (true) {}
        }
    }
    

    运行将创建两个将永远运行的线程。一个是运行程序启动的主线程,另一个是main方法内部启动的线程:

    修改上面的代码,去掉main方法中对runForever的调用...

    public static void main(String[] args) {
        Thread thread = new Thread(new OwnThread());
        thread.start();
    }
    

    ...将导致不同的线程图片:

    这里主线程消失了,因为它被终止了。但另一个启动的线程仍在运行。

    旁注:突然出现另一个线程 - DestroyJavaVM。查看帖子DestroyJavaVM thread ALWAYS running 了解更多信息。

    【讨论】:

    • 但是为什么其他线程已经exited 还在运行呢?
    • @daniu 它正在运行,因为它没有终止(或如您所说的那样退出)。
    • OP 确实声明他在调试时发现“最后调用的方法是线程类的 exit() 方法”。
    • @daniu 嗯...这是因为一个线程被终止了:主线程!我还是讲我的例子。我认为,OPs 问题反之亦然。主线程仍在运行,但另一个线程已终止。这意味着主线程仍在做某事。
    • @DavidStuder 嗯。我会说,在您的示例中,两个线程都已正确终止。在这种情况下,应用程序(Java VM)也应该终止。
    猜你喜欢
    • 2016-05-07
    • 2023-01-11
    • 1970-01-01
    • 2017-08-10
    • 2017-07-03
    • 1970-01-01
    • 2021-01-15
    • 1970-01-01
    • 2012-09-08
    相关资源
    最近更新 更多