程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA編程入門知識 >> JAVA進階 JAVA中具有實例緩存的不可變類

JAVA進階 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集合來作為實例緩存。

       下面的例程,它擁有實例緩存和相應的靜態工廠方法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實例放到緩存中,使它可以被重用。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved