为什么有两个正在运行的线程而不是一个?

时间:2019-08-18 11:12:35

标签: java multithreading concurrency scope garbage-collection

因此,在以下内容中:

public class JavaClass {
    public static void main(String[] args) {
        JavaClass clazz = new JavaClass();
        clazz.startCustomThread();

        clazz = new JavaClass();
        clazz.startCustomThread();
    }

    public void startCustomThread() {
        new MyThread().startThread();
    }

    private static class MyThread {
        public void startThread() {
            new Thread(() -> {
                System.out.println("In thread " + Thread.currentThread().getName());
                while (true) {
                    try {
                        Thread.sleep(1000 * 5);
                        System.out.println("Woke up " + Thread.currentThread().getName());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

            }).start();
        }
    }
}

输出为:

In thread Thread-1
In thread Thread-0
Woke up Thread-0
Woke up Thread-1
....  

由于clazz应该在第二个实例之后进行GC处理,并且第一个线程在对startCustomThread()的第一次调用的本地范围内启动
我的问题是为什么第一个线程不会终止?

3 个答案:

答案 0 :(得分:2)

您两次调用startCustomThread方法,因此您已经启动了2个线程。

来自Thread文档:

  

Java虚拟机将继续执行线程,直到发生以下任何一种情况为止:

     
      
  1. 已调用Runtime类的退出方法,并且安全管理器已允许进行退出操作。
  2.   
  3. 不是所有守护进程线程的所有线程都已死亡,要么通过从调用返回到run方法,要么通过抛出传播到run方法之外的异常引发。
  4.   

这些选项均不适用于您的情况,因此线程仍然存在。这与垃圾回收无关。

答案 1 :(得分:2)

如果您要特别询问为何未对JavaClass objcet进行GC处理。可能是这样(取决于VM参数)。

如果您问为什么该对象产生的线程为什么继续运行,这是因为它创建了新的Thread并运行它。仅当run()方法正常完成或调用System.exit()时,此操作才能完成。

答案 2 :(得分:1)

clazz = new JavaClass();行只是将新对象分配给您的本地引用,而不会破坏该引用所引用的先前创建的对象。此行不能保证对象是垃圾回收。

对象的垃圾回收也不一定与线程的生命周期相关-您的线程可以被中断或完成其执行,但对象仍可能存在于堆中并正在等待GC。