java 缓存的简单实现

实现一个简单的缓存,具有缓存添加,获取,删除,过期自动删除等,主要存储方式为Map

首先建一个缓存数据实体类,用到了lombok消除get set 和全参构造函数

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@AllArgsConstructor
public class CacheEntity {
	/**
	 * 数据主体
	 */
	private Object data;
	
	/**
	 * 超时时长,0永不超时
	 */
	private Long timeout; 
	
	/**
	 * 缓存设置初始时间
	 */
	private Long initialTime;
}

再建一个缓存具体操作接口,支持对缓存的各种操作

import java.util.Map;
import java.util.Set;

public interface CacheManager {
	/**
	 * 存入缓存
	 * @param key
	 * @param data
	 */
	void put(String key, CacheEntity cacheData);
	
	/**
	 * 存入缓存
	 * @param key
	 * @param data
	 * @param timeout
	 */
	void put(String key, Object data, Long timeout);
	
	/**
	 * 获取缓存
	 * @param key
	 * @return
	 */
	CacheEntity getCacheByKey(String key);
	
	/**
	 * 获取所有缓存
	 * @return
	 */
	Map getCacheAll();
	
	/**
	 * 判断缓存是否存在
	 * @param key
	 * @return
	 */
	boolean isExist(String key);
	
	/**
	 * 清除所有缓存
	 */
	void clearAll();
	
	/**
	 * 清除对应缓存
	 * @param key
	 */
	void clearByKey(String key);
	
	/**
	 * 缓存是否失效
	 * @param key
	 * @return
	 */
	boolean isTimeOut(String key);
	
	/**
	 * 获取所有key
	 * @return
	 */
	Set getKeys();	
}

对缓存接口实现,主要运用ConcurrentHashMap来保证多线程读写

import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

public class CacheManagerImpl implements CacheManager{
	
	private static volatile CacheManagerImpl INSTANCE;
	
	private static Map caches = new ConcurrentHashMap<>();
	
	private  CacheManagerImpl() {
	}
	
	public static CacheManagerImpl getInstance() {
		if (INSTANCE == null) {
             synchronized (CacheManagerImpl.class) {
                 if (INSTANCE == null) {
                	 INSTANCE = new CacheManagerImpl();
                 }
             }
         }
         return INSTANCE;
	}

	@Override
	public void put(String key, CacheEntity cacheData) {
		caches.put(key, cacheData);
	}

	@Override
	public void put(String key, Object data, Long timeout) {
		timeout = timeout > 0? timeout : 0L;
		put(key, new CacheEntity(data, timeout, System.currentTimeMillis()));
	}

	@Override
	public CacheEntity getCacheByKey(String key) {
		if(this.isExist(key))
			return caches.get(key);
		return null;
	}

	@Override
	public Map getCacheAll() {
		return caches;
	}

	@Override
	public boolean isExist(String key) {
		return caches.containsKey(key);
	}

	@Override
	public void clearAll() {
		caches.clear();
	}

	@Override
	public void clearByKey(String key) {
		if (this.isExist(key)) {
			caches.remove(key);
		}
	}

	@Override
	public boolean isTimeOut(String key) {
		if (!this.isExist(key)) {
			return true;
		} 
		
		CacheEntity cacheEntity = caches.get(key);
		Long timeOut = cacheEntity.getTimeout();
		Long initialTime = cacheEntity.getInitialTime();
		
		if (timeOut == 0 || System.currentTimeMillis() - initialTime < timeOut) {
			return false;
		} 
		return true;
		
	}

	@Override
	public Set getKeys() {
		return caches.keySet();
	}

}

然后再新建一个线程对该缓存进行监听,来处理过期数据

import java.util.Set;

public class CacheListener {
	private CacheManager cacheManager;
	
	public CacheListener(CacheManager cacheManager) {
		this.cacheManager = cacheManager;
	}
	
	public void startListen() {
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				while(true) {
					Set keys = cacheManager.getKeys();
					
					for (String key : keys) {
						if(cacheManager.isTimeOut(key)) {
							cacheManager.clearByKey(key);
							System.out.println(key + " 被清除了");
						}
					}
					
					try {
						Thread.sleep(5000);
						System.out.println("休息5s再检查");
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}).start();
	}
}

最后测试类如下

import java.util.Arrays;
import java.util.concurrent.TimeUnit;

public class TestCache {
	public static void main(String[] args) {
		CacheManager cacheManager = CacheManagerImpl.getInstance();
		cacheManager.put("testtimeout", "kkkkkkkkk", 20 * 1000L);
		cacheManager.put("test1", "111111111", 0L);
		cacheManager.put("test2", "222222222222222", 100 * 1000L);
		cacheManager.put("test3", "33333333333333", 0L);
		CacheListener cacheListener = new CacheListener(cacheManager);
		cacheListener.startListen();
		
		System.out.println("getCacheAll : " + Arrays.asList(cacheManager.getCacheAll()));
		System.out.println("getCacheKeyAll : " + Arrays.asList(cacheManager.getKeys()));
		System.out.println("getKey : " + Arrays.asList(cacheManager.getCacheByKey("test1")));
		System.out.println("isExist false: " + Arrays.asList(cacheManager.isExist("test")));
		System.out.println("isExist true: " + Arrays.asList(cacheManager.isExist("test1")));
		System.out.println("istimeOut false: " + Arrays.asList(cacheManager.isTimeOut("test1")));
		
		try {
			 TimeUnit.SECONDS.sleep(30);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		System.out.println("isExist : " + Arrays.asList(cacheManager.isExist("testtimeout")));
	}
}

运行结果:

java 缓存的简单实现_第1张图片

你可能感兴趣的:(java)