0

我有一个 Java ThreadFactory 实现,在我的 Android 应用程序中产生可运行的线程子类对象。此应用程序要求所有衍生线程在某个事件触发之前都是可寻址的,并且在触发所述事件时,可以使衍生线程有资格进行垃圾收集(例如,引用计数为 0)。我在想,为了满足第一个要求,我只需维护我的线程对象的 ArrayList,并且效果很好。第二个要求带来了麻烦,这让我想到了一系列关于 Java 引用计数的问题:

问题 1:简单地将生成线程的引用存储在 ArrayList 或其他容器中会增加每个线程对象的引用计数吗?如果我从不存储它们,而是允许我的工厂创建它们并让它们在没有任何定义的句柄的情况下运行,那么每个线程对象的引用计数会是多少,如下所示?

mvThreadSource.newThread(new BackgroundThread(...)).run();

问题 2:下面的代码示例是否对 hTempThread 指向的实际线程对象做任何事情,而不是增加并立即减少其引用计数?

BackgroundThread hTempThread;
for(int i=0;i<mvThreadsVector.size();i++){
    hTempThread = mvThreadsVector.get(i); //probably increments ref count of thread
    hTempThread = null; //probably just decrements the ref count of thread back to 
                        //previous value
}

问题 3:假设问题 2 的答案是“否”,那么存储由 ThreadFactory 实现产生的线程以便它们的引用计数可以按需减少到 0 的有效方法是什么?删除这些引用所涉及的正确语法是什么?下面的代码示例是否会有效地将所有涉及的对象(mvThreadsVector、tempThreads、mvThreadsVector 跟踪的每个线程对象)引用计数减少到 0?clear() 究竟对存储在 arraylist 中的对象的引用计数做了什么,将数组引用设置为 null 对存储在其中的元素的引用计数(如果有的话)有什么作用?

Object[] tempThreads = mvThreadsVector.toArray();
mvThreadsVector.clear(); //possible this line is all I need...
mvThreadsVector = null;
for(int i=0;i<tempThreads.length;i++){
    tempThreads[i] = null;
}
tempThreads = null;

对于上述任何/所有问题的任何帮助将不胜感激!

4

1 回答 1

1
  1. 如果您的线程正在运行,则在它完成执行之前,它将保留在内存中(或交换),而不是 GC。即使线程没有你的代码引用它但正在执行代码,它至少在内部有一个引用。

  2. 你甚至不能保证它会增加和减少引用计数。编译器可以通过意识到第一个赋值没有效果(因为它立即被覆盖)来优化它并将其删除。

  3. 引用计数将减少,但请记住,您可能在引用链中有循环,其中每个元素将有 1 个引用计数,但整个循环不可访问,正确的 GC 应该意识到这一点并将其删除。

我认为主要问题是你不应该指望线程的引用计数下降到 0。只要它们正在运行,您就应该假设它们具有引用,因此您还必须有一种方法来确保线程停止执行。

于 2013-01-30T00:22:10.723 回答