Java中共享对象的创建与销毁详解(附源码)

前言

在上一篇文章的示例中还应该注意到,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,这样可以防止溢出。idfinal的,因为我们不希望它的值在对象生命周期中被改变。

在将一个共享对象附着到类上时,必须记住调用addRef(),但是dispose()方法将跟踪引用数,并决定何时执行清理。使用这种技巧需要加倍地细心,但是如果你正在共享需要清理的对象,那么你就没有太多的选择余地了。

时间: 2024-11-08 07:21:29

Java中共享对象的创建与销毁详解(附源码)的相关文章

JAVA代码重用机制复用类之继承语法(附源码)

前言 继承是所有OOP语言和Java语言不可缺少的组成部分.当创建一个类时,总是在继承,因此,除非已明确指出要从其他类中继承,否则就是在隐式地从Java的标准根类Object进行继承. 组合的语法比较平实,但是继承使用的是一种特殊语法.在继承过程中,需要先声明"新类与旧类相似".这种声明是通过在类主体的左边花括号之前,书写后面紧随基类名称的关键字extends而实现的.当这么做时,会自动得到基类中所有的域和方法.例如: 示例源码 基类 package com.mufeng.thesev

在网站开中很有用的8个 jQuery 效果【附源码】

jQuery 作为最优秀 JavaScript 库之一,改变了很多人编写 JavaScript 的方式.它简化了 HTML 文档遍历,事件处理,动画和 Ajax 交互,而且有成千上万的成熟 jQuery 插件可供使用.看看下面这些惊人的功能和效果,我相信你会发现一些很有用的东西. 基于 jQuery 实现的 Ajax 异步分页 jPages 是一款非常不错的客户端分页插件,有很多特色,例如自动播放.按键翻页.延迟加载等等 源码下载      在线演示 老牌的响应式 jQuery 幻灯片效果 Sl

Java中的String,StringBuffer,StringBuilder详解与区别

1.String Java中string类是不可变的,其中在声明的源代码中用的final,所以只能声明一次.所以每次在明面上的改变其实是重新生成一个String对象,指针指向新的String对象.同时,String内部重写的了equal的方法,原本Object的equal就是两个对象相等就可以,但是现在,并不能靠对象相等来判断值相等了,重写的equal中会挨个比较字符,这也就是为啥比较同样内容字符串要用equal的原因. 同时String a="111"+"222"

Java中的String为什么是不可变的? -- String源码分析

转:http://blog.csdn.net/zhangjg_blog/article/details/18319521 什么是不可变对象? 众所周知, 在Java中, String类是不可变的.那么到底什么是不可变的对象呢? 可以这样认为:如果一个对象,在它创建完成之后,不能再改变它的状态,那么这个对象就是不可变的.不能改变状态的意思是,不能改变对象内的成员变量,包括基本数据类型的值不能改变,引用类型的变量不能指向其他的对象,引用类型指向的对象的状态也不能改变. 区分对象和对象的引用 对于Ja

经验分享-Java中JDK和JRE区别和误区详解!

1.了解基本的java概念.JDK和JRE基本了解 1.1)Java SE (原J2SE) Java Platform, Standard Edition    -- Java标准平台 1.2) Java EE (原J2EE) Java Platform, Enterprise Edition -- Java企业级应用平台 1.3)Java ME (原J2ME) Java Platform, Micro Edition      -- Java微系统应用平台 ##################

C++/Java中继承关系引发的调用关系详解

C++: 这里引用到了 http://blog.csdn.net/haoel/article/details/1948051/ 中的内容,还请提前阅读陈大神的这篇博客后在阅读本篇. 覆盖,实现多态的基础,通过虚函数表来实现,下面这个例子便是覆盖 Override 1 #include<iostream> 2 3 using namespace std; 4 5 class Base{ 6 public: 7 Base(){ 8 cout << "Base::Base&qu

Cocos2dx-3.x 中CCCamera相机类详解及源码分析

Cocos2d-x 3.3版本中加入了相机这个类,该类在3D游戏中是必不可少的,在3D立体游戏中,往往需要视野角度的变化,通过相机的变换才能观察和体验整个游戏世界. CCCamera类基本使用 在游戏中一般有两种类型的相机:一种是透视相机,它在3D游戏中十分常见:另一种是正交相机,它没有透视相机的近大远小的效果而是相机内任何位置的物体大小比例都是一样的. 上图是透视相机的原理图,一般来说,我们通过以下代码创建: _camera = Camera::createPerspective(60, (G

Servlet容器Tomcat中web.xml中url-pattern的配置详解[附带源码分析]

前言 今天研究了一下tomcat上web.xml配置文件中url-pattern的问题. 这个问题其实毕业前就困扰着我,当时忙于找工作. 找到工作之后一直忙,也就没时间顾虑这个问题了. 说到底还是自己懒了,没花时间来研究. 今天看了tomcat的部分源码 了解了这个url-pattern的机制.  下面让我一一道来. tomcat的大致结构就不说了, 毕竟自己也不是特别熟悉. 有兴趣的同学请自行查看相关资料. 等有时间了我会来补充这部分的知识的. 想要了解url-pattern的大致配置必须了解

详解Redis源码中的部分快速排序算法(pqsort.c)

看标题,你可能会疑惑:咦?你这家伙,怎么不讲解完整的快排,只讲一部分快排---.- 哎,冤枉."部分快排"是算法的名字,实际上本文相当详细呢.本文几乎与普通快排无异.看懂了本文,你对普通的快排也会有更深的认识了. 快速排序算法(qsort)的原理我们大都应该了解.本文介绍的是部分快速排序算法.其实其算法本质是一样的,只不过限定了排序的左右区间,也就是只对一个数字序列的一部分进行排序,故称为"部分快速排序算法",简称:pqsort Redis项目中的pqsort.c