1. 程式人生 > >快取機制:java中快取的原理

快取機制:java中快取的原理

外存:

  也就是我們經常說的(CDEF盤的大小)外儲存器是指除計算機記憶體及CPU快取以外的儲存器,此類儲存器一般斷電後仍然能儲存資料。常見的外儲存器有硬碟、軟盤、光碟、U盤等,一般的軟體都是安裝在外存中

記憶體:

  記憶體是計算機中重要的部件之一,它是與CPU進行溝通的橋樑。計算機中所有程式的執行都是在記憶體中進行的,因此記憶體的效能對計算機的影響非常大。記憶體(Memory)也被稱為記憶體儲器,其作用是用於暫時存放CPU中的運算資料,以及與硬碟等外部儲存器交換的資料。只要計算機在執行中,CPU就會把需要運算的資料調到記憶體中進行運算,當運算完成後CPU再將結果傳送出來,記憶體的執行也決定了計算機的穩定執行,此類儲存器一般斷電後資料就會被清空

快取記憶體:

  快取記憶體是用來協調CPU與主存之間存取速度的差異而設定的。一般情況下,CPU的工作速度高,但記憶體的工作速度相對較低,為了解決這個問題,通常使用快取記憶體,快取記憶體的存取速度介於CPU和主存之間。系統將一些CPU在近幾個時間段經常訪問的內容存入高速緩衝,當CPU需要使用資料時,先在快取記憶體中找,如果找到,就不必訪問記憶體了,找不到時,再找記憶體,這樣就在一定程度上緩解了由於主存速度低造成的CPU“停工待料”的情況

---------------------------------------------------------------------------------------------------------------------------

  之前一直很不理解這個快取那個快取,其實快取就是把一些外存上的資料儲存到記憶體上而已,怎麼儲存到記憶體上呢,我們執行的所有程式,裡面的變數值都是放在記憶體上的,所以說如果要想使一個值放到記憶體上,實質就是在獲得這個變數之後,用一個生存期較長的變數存放你想存放的值,在java中一些快取一般都是通過map集合來做的。 

在Java中經常用到快取,在SSh框架中也會用到一級快取和二級快取,到底快取是怎麼實現的呢?

  簡單講就是,如果某些資源或者資料會被頻繁的使用,而這些資源或資料儲存在系統外部,比如資料庫、硬碟檔案等,那麼每次操作這些資料的時候都從資料庫或者硬碟上去獲取,速度會很慢,會造成效能問題。   一個簡單的解決方法就是:把這些資料快取到記憶體裡面,每次操作的時候,先到記憶體裡面找,看有沒有這些資料,如果有,那麼就直接使用,如果沒有那麼就獲取它,並設定到快取中,下一次訪問的時候就可以直接從記憶體中獲取了。從而節省大量的時間,當然,快取是一種典型的空間換時間的方案。

  在Java中最常見的一種實現快取的方式就是使用Map, 基本的步驟是:   1.先到快取裡面查詢,看看是否存在需要使用的資料   2.如果沒有找到,那麼就建立一個滿足要求的資料,然後把這個資料設定回到快取中,以備下次使用   3.如果找到了相應的資料,或者是建立了相應的資料,那就直接使用這個資料。

複製程式碼

/**
* Java中快取的基本實現示例
*/
public class JavaCache {
    /**
    * 快取資料的容器,定義成Map是方便訪問,直接根據Key就可以獲取Value了
    * key選用String是為了簡單,方便演示
    */
    private Map<String,Object> map = new HashMap<String,Object>();
    /**
    * 從快取中獲取值
    
    * @param key 設定時候的key值
    * @return key對應的Value值
    */
    public Object getValue(String key){
        //先從快取裡面取值
        Object obj = map.get(key);
        //判斷快取裡面是否有值
        if(obj == null){
            //如果沒有,那麼就去獲取相應的資料,比如讀取資料庫或者檔案
            //這裡只是演示,所以直接寫個假的值
            obj = key+",value";
            //把獲取的值設定回到快取裡面
            map.put(key, obj);
        }
        //如果有值了,就直接返回使用
        return obj;
    }
}

複製程式碼

  這裡只是快取的基本實現,還有很多功能都沒有考慮,比如快取的清除,快取的同步等等。當然,Java的快取還有很多實現方式,也是非常複雜的,現在有很多專業的快取框架,更多快取的知識,這裡就不再去討論了。 下面用單例模式實現快取:

複製程式碼

/**
* 使用快取來模擬實現單例
*/
public class Singleton {
    /**
    * 定義一個預設的key值,用來標識在快取中的存放
    */
    private final static String DEFAULT_KEY = "One";
    /**
    * 快取例項的容器
    */
    private static Map<String,Singleton> map =
    new HashMap<String,Singleton>();
    /**
    * 私有化構造方法
    */
    private Singleton(){
    //
    }
    public static Singleton getInstance(){
        //先從快取中獲取
        Singleton instance = (Singleton)map.get(DEFAULT_KEY);
        //如果沒有,就新建一個,然後設定回快取中
        if(instance==null){
            instance = new Singleton();
            map.put(DEFAULT_KEY, instance);
        }
        //如果有就直接使用
        return instance;
    }
}

複製程式碼