3

我有一个关于线程的问题。当我这样做时:

new Thread(new Runnable(){

        @Override
        public void run() {
            //sth to do
        }

    }).start();

执行 run() 中的所有代码时会发生什么?系统会自动删除线程还是线程仍然保留在内存中?

谢谢和问候

4

4 回答 4

3

当一个线程完成其 run() 方法时,它将进入“死”状态。然后堆栈中的下一个线程在之后运行。

死状态:

“当一个线程的 run() 方法完成时,它被认为是死的。它可能仍然是一个可行的 Thread 对象,但它不再是一个单独的执行线程。一旦一个线程死了,它就永远无法复活!(整个“我看到死线程”的事情。)如果你在一个死线程实例上调用 start(),你会得到一个运行时(而不是编译器)异常。而且可能不需要火箭科学家告诉你,如果一个线程死了,它不再被认为是活着的。”

于 2013-05-12T13:35:48.623 回答
1

Java 的线程模型比这要复杂一些。

基本上,java.lang.Thread 只是一些数据的包装器,而不是一个进程本身。当您调用该.start()方法时,会创建一个本机线程并将其链接到您的 java 线程。这项工作由 JVM 使用内部数据结构 (JavaThreadOSThread) 完成。

方法完成后,.run()JVM 会执行许多操作以删除使用的本机线程。因此,您将不会再在进程列表中看到该线程(例如,使用topor ps)。

但是,在堆中分配的对象和 java.lang.Thread 实例本身会保留在内存中,直到 GC 循环收集它们。

所以,总结一下:

  • 是的,JVM 删除了使用的本机线程

  • 不,JVM 不会删除使用的 java.lang.Thread 实例

  • GC 最终会收集到这个实例

有关更多信息,您应该阅读 Charlie Hunt 所著的《Java Performance》一书。它包含有关该主题(以及许多其他主题)的大量信息。

希望有帮助!

于 2013-05-13T11:52:50.533 回答
0

当线程中的代码完成执行时,线程停止。
Thread实例在被 GC 之前仍然存在,但实际的系统线程将不再存在。

于 2013-05-12T13:31:02.693 回答
0

如果您不使用任何自定义配置的线程池机制,您的线程将会死掉,并且Thread对象本身将有资格进行垃圾回收。

于 2013-05-12T13:31:39.467 回答