<%@ page contentType="text/html; charset=gb2312"%> JAVA中具有实例缓存的不可变类
网站公告:   ◆北天JAVA技术网热情为java爱好者服务,本网内容包括JAVA(JSP、servlet、EJB、webservice、j2ee、javabean、应用服务器、JavaScript),数据库(MYSQL、SQL Server、Sybase、Oracle、DB2、数据库综合知识),设计研究(设计模式、Struts、Spring、Hibernate、设计框架、设计综合知识),WEB2.0新技术(主要介绍AJAX),以及各种技术的入门、实例、例子等等,欢迎各位多来坐坐!◆  诚邀各位JAVA爱好者加盟!◆  本网站内容丰富,更新快,保证每周20篇以上!  
加入收藏
设为首页
联系站长
承接项目
  相关资源:网站首页 | 免费培训学院 | 技术论坛 | JAVA聊天室 | 作家专栏 | 开发工具 | 认证考试 | 会员俱乐部
  JAVA技术初学者园地 | jsp与servlet | javascript | Java源代码 | EJB | web service | 应用服务器 | JAVA综合知识
  设计研究设计模式 | 设计框架 | Struts | Spring | Hibernate | 开源项目 | 面向对象设计 | 设计综合知识
  数 据 库MYSQL | SQL Server | Sybase | Oracle | DB2 | Informix | Access | 数据库综合知识
  其他资源:AJAX新技术 | 网站开发 | ERP软件 | OA办公软件 | 商业智能BI | 开发综合知识 | 承接项目 | 项目试用

 
 
JAVA中具有实例缓存的不可变类
     发布者: 发布时间:2007-12-05
 

不可变类的实例的状态不会变化,这样的实例可以安全地被其他与之关联的对象共享,还可以安全地被多个线程共享。为了节省内存空间,优化程序的性能,应该尽可能地重用不可变类的实例,避免重复创建具有相同属性值的不可变类的实例。

JDK 1.5的基本类库中,对一些不可变类,如Integer类做了优化,它具有一个实例缓存,用来存放程序中经常使用的Integer实例。JDK 1.5的Integer类新增了一个参数,为int类型的静态工厂方法valueOf(int i),它的处理流程如下:

if(在实例缓存中存在取值为i的实例)
   
直接返回这个实例
else{
  
用new语句创建一个取值为i的Integer实例
  
把这个实例存放在实例缓存中
  
返回这个实例
}

在以下程序代码中,分别用new语句和Integer类的valueOf(int i)方法来获得Integer实例。

Integer a=new Integer(10);
Integer b=new Integer(10);

Integer c=Integer.valueOf(10);
Integer d= Integer.valueOf(10);

System.out.println(a==b); //打印false
System.out.println(a==c); //打印false

System.out.println(c==d); //打印true

       以上代码共创建了3个Integer对象,每个new语句都会创建一个新的Integer对象。而Integer.valueOf(10)方法仅在第一次被调用时,创建取值为10的Integer对象,在第二次被调用时,直接从实例缓存中获得它。由此可见,在程序中用valueOf()静态工厂方法获得Integer对象,可以提高Integer对象的可重用性。

     到底如何实现实例的缓存呢?缓存并没有固定的实现方式,完善的缓存实现不仅要考虑何时把实例加入缓存,还要考虑何时把不再使用的实例从缓存中及时清除,以保证有效合理地利用内存空间。一种简单的实现是直接用Java集合来作为实例缓存。

     下面的例程,它拥有实例缓存和相应的静态工厂方法valueOf()。Name类的实例缓存中可能会加入大量Name对象,为了防止耗尽内存,在实例缓存中存放的是Name对象的软引用(SoftReference)。如果一个对象仅仅持有软引用,Java虚拟机会在内存不足的情况下回收它的内存。

例程11-12 Name.java

import java.util.Set;
import java.util.HashSet;
import java.util.Iterator;
import java.lang.ref.*;

public class Name {

//实例缓存,存放Name对象的软引用

private static final Set>   names=new HashSet>();

public static Name valueOf(String firstname, String lastname){ //静态工厂方法

 Iterator> it=names.iterator();

 while(it.hasNext()){
  
SoftReference  ref=it.next();//获得软引用
  
Name name=ref.get();//获得软引用所引用的Name对象
 
if(name!=null&& name.firstname.equals(firstname)&& name.lastname.equals(lastname))
   
return name;
 }

 //如果在缓存中不存在Name对象,就创建该对象,并把它的软引用加入到实例缓存

 Name name=new Name(firstname,lastname);
 names.add(new SoftReference(name));
 return name;

}

public static void main(String args[]){

  Name n1=Name.valueOf("小红","王");
  
Name n2=Name.valueOf("小红","王");
  
Name n3=Name.valueOf("小东","张");
  
System.out.println(n1);
  
System.out.println(n2);
  
System.out.println(n3);
   
System.out.println(n1==n2); //打印true
 
}

 }

在程序中,既可以通过new语句创建Name实例,也可以通过valueOf()方法创建Name实例。在程序的生命周期中,对于程序不需要经常访问的Name实例,应该使用new语句创建它,使它能及时结束生命周期;对于程序需要经常访问的Name实例,那就用valueOf()方法来获得它,因为该方法能把Name实例放到缓存中,使它可以被重用。

Tips

      从例程11-12的Name类也可以看出,在有些情况下,一个类可以同时提供public的构造方法和静态工厂方法。用户可以根据实际需要,灵活地决定到底以何种方式获得类的实例。

    另外要注意的是,没有必要为所有的不可变类提供实例缓存。随意创建大量实例缓存,反而会浪费内存空间,降低程序的运行性能。通常,只有满足以下条件的不可变类才需要实例缓存。

1. 不可变类的实例的数量有限。
2.在程序运行过程中,需要频繁访问不可变类的一些特定实例。这些实例拥有与程序本身同样长的生命周期。


TAG:



(转载文章请保留出处:北天JAVA技术网(www.java114.com))
 
更多精彩文章:
深入探讨、理解Java的CLASSPATH
JAVA基础知识精华总结
JSP、Struts避免Form重复提交的几种方案
Java语言中的ClassLoader与Package机制
WSDL 版本 1.1 规范
SOAP 版本 1.1 规范
 
最近评论:
        
鍥炲
        
那个雨天的想法!
wow gold,wow power leveling.wow power leveling,wow power leveling, max(7124)
        
如果真的有来生!
四川旅游,九寨沟旅游,稻城亚丁旅游,四姑娘山旅游,海螺沟旅游,西藏旅游, max(3748)
        
如果真的有来生!
四川旅游,九寨沟旅游,稻城亚丁旅游,四姑娘山旅游,海螺沟旅游,西藏旅游, max(6232)
        
轻轻走过你的窗前!
world of warcraft gold,cheap world of warcraft gold,warcraft gold,world of warcraft gold,cheap world of warcraft gold,warcraft gold max(3997)
        
不在的哪天!
final fantasy xi gil,final fantasy xi gil,final fantasy xi gil,final fantasy xi gil, max(4652)
        
没有情人的情人节!
wow gold,wow power leveling.wow power leveling,wow power leveling, max(6242)
        
没有情人的情人节!
wow gold,wow power leveling.wow power leveling,wow power leveling, max(9471)
        
没有情人的情人节!
wow gold,wow power leveling.wow power leveling,wow power leveling, max(2316)
        
没有情人的情人节!
wow gold,wow power leveling.wow power leveling,wow power leveling, max(8599)
        
标 题:   
内 容:   
 
                                  
 
免责声明:该文章由网友发表,如果对您造成侵权,请联系站长

首页 - 承接项目 - 网站地图 - 联系我们 -
版权所有北天JAVA技术工作室 ICP证号:粤ICP备06079815号