前言
在上一篇文章的示例中还应该注意到,Frog对象拥有其自己的成员对象。Frog对象创建了它自己的成员对象,并且知道它们存活多久(只要Frog存活着),因此Frog对象知道何时调用dispose()去释放其成员对象。然而,如果这些成员对象中存在于其他一个或者多个对象共享的情况,问题就变得更加复杂了,你就不能简单地假设你可以调用dispose()了。在这种情况下,也就必需使用引用计数来跟踪仍旧访问着共享对象的对象数量了。下面是相关的代码:
示例源码
package com.mufeng.theeighthchapter; class Shared { private int refcount = 0; private static long counter = 0; private final long id = counter++; public Shared() { // TODO Auto-generated constructor stub System.out.println("Creating " + this); } public void addRef() { refcount++; } protected void dispose() { if (--refcount == 0) { System.out.println("Disposing " + this); } } @Override public String toString() { // TODO Auto-generated method stub return "Shared " + id; } } class Composing { private Shared shared; private static long counter = 0; private final long id = counter++; public Composing(Shared shared) { // TODO Auto-generated constructor stub System.out.println("creating " + this); this.shared = shared; this.shared.addRef(); } protected void dispose() { System.out.println("disposing " + this); shared.dispose(); } @Override public String toString() { // TODO Auto-generated method stub return "Composing " + id; } } public class ReferenceCount { public static void main(String[] args) { Shared shared = new Shared(); Composing[] composing = { new Composing(shared), new Composing(shared), new Composing(shared), new Composing(shared), new Composing(shared) }; for (Composing c : composing) { c.dispose(); } } }
输出结果
Creating Shared 0 creating Composing 0 creating Composing 1 creating Composing 2 creating Composing 3 creating Composing 4 disposing Composing 0 disposing Composing 1 disposing Composing 2 disposing Composing 3 disposing Composing 4 Disposing Shared 0
源码解析
static long counter跟踪所创建的Shared的示例的数量,还可以为id提供数值。counter的类型是long而不是int,这样可以防止溢出。id是final的,因为我们不希望它的值在对象生命周期中被改变。
在将一个共享对象附着到类上时,必须记住调用addRef(),但是dispose()方法将跟踪引用数,并决定何时执行清理。使用这种技巧需要加倍地细心,但是如果你正在共享需要清理的对象,那么你就没有太多的选择余地了。
时间: 2024-11-08 07:21:29