【问题标题】:approach to null all references to objects created by a Java ThreadFactory使对 Java ThreadFactory 创建的对象的所有引用无效的方法
【发布时间】:2013-01-29 20:39:42
【问题描述】:

我有一个 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;

非常感谢任何/所有上述问题的帮助!

【问题讨论】:

  • 建议您将其分解并提出多个问题。

标签: java multithreading runnable reference-counting abstract-factory


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

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

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

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

【讨论】:

  • 好吧,这就是我的想法。鉴于“如果你的线程正在运行,直到它完成执行,它将被保存在内存中(或交换)而不是 GC”,如果在应用程序关闭之前它的执行从未停止,线程会发生什么?线程分配的内存是否会被系统释放(当前系统上下文是 Android 2.3.3,尽管深入了解 JVM 对这种情况的处理也会很有用)?谢谢!
  • 正常关闭意味着停止所有线程(不是使用 Thread.stop,不是最好的主意),而是其他一些机制。那时,应用程序将自行停止。不那么温和的关闭(即终止应用程序/进程)将释放所有内存,包括在其中运行的线程。线程始终在包含的进程/应用程序中运行,线程不拥有资源,进程拥有。
猜你喜欢
  • 2015-07-06
  • 2011-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-10
  • 2022-11-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多