JAVA进阶 JAVA中具有实例缓存的不可变类

2016-02-19 20:27 1 1 收藏

今天天气好晴朗处处好风光,好天气好开始,图老师又来和大家分享啦。下面给大家推荐JAVA进阶 JAVA中具有实例缓存的不可变类,希望大家看完后也有个好心情,快快行动吧!

【 tulaoshi.com - 编程语言 】

 

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

  在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虚拟机会在内存不足的情况下回收它的内存。

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)

  例程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
   }

   }

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)

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

来源:http://www.tulaoshi.com/n/20160219/1623718.html

延伸阅读
Java 5之后提供优秀的并发库util.concurrent,.Net中缺乏类似的功能。由于硬件体系发生了变化,多核时代来临,.NET中缺乏并发类库显然不合时宜。缓解这一矛盾的其中一个办法就是在往 C# 中移植java的 util.concurrent 。 java中的util.concurrent包中提供了一个类LockSupport,util.concurrent包很多关键实现需要调用LockSupport。...
一个简单的例子 代码如下: //a simple demo import java.util.HashMap; import java.util.Set; public class TestHashMap {     public static void main(String[] args) {         HashMapInteger, Integer G = new HashMapInteger,Integer();       &n...
  随着Internet的迅速发展,电子商务的浪潮势不可挡,日常工作和数据传输都放在Internet网上进行传输,大大提高了效率,降低了成本,创造了良好的效益。但是,由于Internet网络协议本身存在着重要的安全问题(IP包本身并不继承任何安全特性,很容易伪造出IP包的地址、修改其内容、重播以前的包以及在传输途中拦截并查看包的内容),使网上的信息传输...
       Java是一种面向对象(OOP)的编程语言;在Java中,面向对象是以类的形式出现的,而对象则是类的实例,所以要学习Java的类首先必须了解面向对象。面向对象编程不同于过程语言或结构化程序设计,他存在对象这个概念,面向对象中的对象不仅是数据结构,还包含和数据结构有关的方法。 一:类 1.类...
1、属于javax.swing 包。 2、功能:定制四种不同种类的标准对话框。 ConfirmDialog 确认对话框。提出问题,然后由用户自己来确认(按"Yes"或"No"按钮) InputDialog 提示输入文本 MessageDialog 显示信息 OptionDialog 组合其它三个对话框类型。 3、这四个对话框可以采用showXXXDialog()来显示。如: showConfirmDialog() 显示确认对...

经验教程

431

收藏

15
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部