使用静态列表在Java中保存所有线程

3

你好,我希望使用静态列表来保存所有正在运行的线程,例如:

public class MyClass {
    public static final List<Thread> threads = new ArrayList<>();
    public static void main(String[] args) throws InterruptedException {
        new Thread(() -> {
            MyClass.threads.add(Thread.currentThread());
            try {
                Thread.sleep(2000);
            } catch (Exception e) {
            }
        }).start();
        for (int i = 0; i < 10; i++) {
            if (!threads.isEmpty()) {
                Thread t = threads.get(0);
                System.out.println(t.isAlive());
            }
            Thread.sleep(1000);
        }
    }
}

上面的代码将会打印出:
true
true
false
false
...

预期的结果是在2秒后线程返回。

我的问题是:线程返回后,添加到静态线程列表中的线程是否会消失?即我是否期望看到线程对象在返回后某个时刻变为null?还是我会无限期地看到线程对象?垃圾收集器在这里起作用吗?


3
线程返回后,如果您不将其移除,则添加到静态线程列表中的线程将不会消失。 - Joe C
2个回答

4

一旦关联的操作系统线程终止,Thread对象并不会神奇地消失。

一旦线程终止,它就不能作为GC根了。但只要其他东西保持对它的引用,比如你的列表,它就会一直存在。

而且无论线程是停止还是中断或其他什么情况,java.lang.Thread都是一个对象,它引用一个系统资源,即实际的线程,只要该线程存活,该对象就会一直存在,但一旦线程终止,它不会销毁对象。只是isAlive返回false,并且你不能再成功调用start方法。

很难想象像你所建议的那样保留线程列表会有什么好处。


1
@user1589188:最好使用线程池而不是专用线程。 - Nathan Hughes
@iser2589288:是的,如果没有其他东西保持对引用的引用。你可以查看弱引用。 - Nathan Hughes
优秀的回答。学习使用Executors,使用线程池而不是管理显式线程。 - Basil Bourque
@user1589188:这就是我们所说的xy问题;你并没有直接询问你的问题x,而是询问了你的解决方案y。也许你应该开一个新的问题来询问你真正的问题。 - Holger
@Holger 或许到那时候有些人会说“你的问题太宽泛了”或者“给我们看看你尝试过什么” :) - user1589188
显示剩余3条评论

1
不,该线程已经停止运行,但您所持有的Thread对象将保留,就像任何其他对象一样。垃圾收集器只能清理没有引用的对象,Thread实例也不例外。

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