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

2014极速王子

2014极速王子

2016-02-19 20:27

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

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

  在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集合来作为实例缓存。

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

       下面的例程,它拥有实例缓存和相应的静态工厂方法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;

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

  }

  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实例放到缓存中,使它可以被重用。

展开更多 50%)
分享

猜你喜欢

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

编程语言 网络编程
JAVA进阶 JAVA中具有实例缓存的不可变类

深入Java不可变类型的详解

编程语言 网络编程
深入Java不可变类型的详解

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

Java Clone(类的复制)实例代码

编程语言 网络编程
Java Clone(类的复制)实例代码

java中Properties类的使用

编程语言 网络编程
java中Properties类的使用

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

java类中使用Jfreechart的简单实例

编程语言 网络编程
java类中使用Jfreechart的简单实例

在JAVA中定义类的结构

编程语言 网络编程
在JAVA中定义类的结构

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

Windows10系统点击关机变成自动重启怎么解决

Windows10系统点击关机变成自动重启怎么解决

CSS Hack汇总快查

CSS Hack汇总快查
下拉加载更多内容 ↓