我有一个关于线程的问题。当我这样做时:
new Thread(new Runnable(){
@Override
public void run() {
//sth to do
}
}).start();
执行 run() 中的所有代码时会发生什么?系统会自动删除线程还是线程仍然保留在内存中?
谢谢和问候
我有一个关于线程的问题。当我这样做时:
new Thread(new Runnable(){
@Override
public void run() {
//sth to do
}
}).start();
执行 run() 中的所有代码时会发生什么?系统会自动删除线程还是线程仍然保留在内存中?
谢谢和问候
当一个线程完成其 run() 方法时,它将进入“死”状态。然后堆栈中的下一个线程在之后运行。
死状态:
“当一个线程的 run() 方法完成时,它被认为是死的。它可能仍然是一个可行的 Thread 对象,但它不再是一个单独的执行线程。一旦一个线程死了,它就永远无法复活!(整个“我看到死线程”的事情。)如果你在一个死线程实例上调用 start(),你会得到一个运行时(而不是编译器)异常。而且可能不需要火箭科学家告诉你,如果一个线程死了,它不再被认为是活着的。”
Java 的线程模型比这要复杂一些。
基本上,java.lang.Thread 只是一些数据的包装器,而不是一个进程本身。当您调用该.start()
方法时,会创建一个本机线程并将其链接到您的 java 线程。这项工作由 JVM 使用内部数据结构 (JavaThread
和OSThread
) 完成。
方法完成后,.run()
JVM 会执行许多操作以删除使用的本机线程。因此,您将不会再在进程列表中看到该线程(例如,使用top
or ps
)。
但是,在堆中分配的对象和 java.lang.Thread 实例本身会保留在内存中,直到 GC 循环收集它们。
所以,总结一下:
是的,JVM 删除了使用的本机线程
不,JVM 不会删除使用的 java.lang.Thread 实例
GC 最终会收集到这个实例
有关更多信息,您应该阅读 Charlie Hunt 所著的《Java Performance》一书。它包含有关该主题(以及许多其他主题)的大量信息。
希望有帮助!
当线程中的代码完成执行时,线程停止。
该Thread
实例在被 GC 之前仍然存在,但实际的系统线程将不再存在。
如果您不使用任何自定义配置的线程池机制,您的线程将会死掉,并且Thread
对象本身将有资格进行垃圾回收。