Java 語言設計一個緩存模型

前提:

數據庫表 student:

create table student(
	id int,
	name varchar(15)
);

一.線程不安全版本

import java.util.HashMap;
import java.util.Map;
 
public class CacheDemo {
 
    //map 用來作緩存模型
    private static Map<String, Object> map = new HashMap<String, Object>();
 
    //根據 key 的值,返回其對應的 value
    public  static Object getValue(String key) {
        Object value = map.get(key);
        if (value == null) {
        	int ID=Integer.value(key);
            value =//去數據庫查詢該 key 對應的 value ( select name from student where id=ID;)
            map.put(key, value);  //將數據放到緩存模型中
        }
        return value;   //map 中存在該 key 對應的值那麼則返回
    }
}

從上面的代碼可以看出,當有 10 個線程同時訪問數據庫的時候,會出現數據查詢的次數也是10次,這樣對數據庫的訪問壓力過大,不推薦使用。


二.線程安全版本

import java.util.HashMap;
import java.util.Map;
 
public class CacheDemo {
 
    // map 用來作緩存模型
    private static Map<String, Object> map = new HashMap<String, Object>();
 
    public synchronized static Object getValue(String key) {
        Object value = map.get(key);
        if (value == null) {
            value = //去數據庫查詢該 key 對應的 value ( select name from student where id=ID;)
            map.put(key, value);   //將數據放到緩存模型中
        }
        return value;
    }
}

從上面的代碼可以看出,在 getValue() 方法上加上 synchronized 後,當有 10 個線程(10 個線程攜帶的 key 值都一樣)都要訪問數據庫的時候,線程之間只有搶到了鎖的線程纔可以訪問數據庫進行數據查詢,因此一定程度上減少了數據庫訪問壓力,但是鎖的粒度比較大。


三.升級版本

import java.util.HashMap;
import java.util.Map;
 
public class CacheDemo {
 
    // map 用來作緩存模型
    private static Map<String, Object> map = new HashMap<String, Object>();
 
    public static Object getValue(String key) {
        Object value = map.get(key);
        if(value==null){
            synchronized (CacheDemo.class){
                if(value==null){
                    value="abc";    //去數據庫查詢該 key 對應的 value ( select name from student where id=ID;)
                    map.put(key,value);//將數據放到緩存模型中
                }
            }
        }
        return value;
    }
}

從上面的代碼可以看出,如果 10 個線程(10 個線程攜帶的 key 值都一樣)訪問的數據已經存在於 map 中了,那麼就不會出現競爭鎖的情況,直接返回 value 即可。但是如果線程訪問的數據不存在於 map 中的時候,纔會出現競爭鎖的情況然後進行數據庫的查詢,並且只有第一個搶到鎖的線程纔可以查詢數據庫,其他的線程拿到鎖以後,發現 value 已經不爲 null 了,直接返回 value 的值即可。

原文來源:https://blog.csdn.net/u010452388/article/details/82725299

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章