Contents

Java 實作 Memory Cache 方法小記

Contents

最近程式會頻繁撈取資料庫
想有沒有減輕資料庫負擔
後來想到之前 swoole 課程有提到 Memory Cache
今天網路找了一下 Java 實作
發現還滿多實作可以直接使用

  1. CachesExplained
  1. GitHub - lixk/ECache: simple memory cache for Java

簡單實用,我是使用這個範例實作
就專案能用

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * simple memory cache
 *
 * @author lixk
 */
public class ECache {
	/**
	 * key-value data set
	 */
	private final static Map<String, Entity> DATA_BASE = new HashMap<>();
	/**
	 * use scheduled executor to clean expired data
	 */
	private final static ScheduledExecutorService CLEANER = Executors.newSingleThreadScheduledExecutor();

	/**
	 * put data to cache
	 *
	 * @param key   unique identification for data
	 * @param value your data
	 */
	public synchronized static void put(String key, Object value) {
		ECache.put(key, value, 0L);
	}

	/**
	 * put data to cache
	 *
	 * @param key    unique identification for data
	 * @param value  your data
	 * @param expire data survival time in milliseconds
	 */
	public synchronized static void put(final String key, final Object value, final long expire) {
		//clean old data
		ECache.remove(key);
		//set schedule task
		if (expire > 0L) {
			Future future = CLEANER.schedule(new Runnable() {
				@Override
				public void run() {
					//remove data
					synchronized (ECache.class) {
						DATA_BASE.remove(key);
					}
				}
			}, expire, TimeUnit.MILLISECONDS);
			DATA_BASE.put(key, new Entity(value, expire, future));
		} else {
			DATA_BASE.put(key, new Entity(value, null, null));
		}
	}

	/**
	 * read data from cache
	 *
	 * @param key unique identification for data
	 * @return data bound to the key
	 */
	public synchronized static <T> T get(String key) {
		Entity entity = DATA_BASE.get(key);
		if (entity != null && entity.isAlive()) {
			return (T) entity.value;
		}
		return null;
	}

	/**
	 * remove cached data
	 *
	 * @param key unique identification for data
	 * @return data bound to the key
	 */
	public synchronized static <T> T remove(String key) {
		//remove data from data set
		Entity entity = DATA_BASE.remove(key);
		if (entity == null) {
			return null;
		}
		//cancel the schedule task
		if (entity.future != null) {
			entity.future.cancel(true);
		}

		return entity.isAlive() ? (T) entity.value : null;
	}

	/**
	 * cached data entity
	 */
	private static class Entity {
		Object value;
		Long expirationTime;
		Future future;

		Entity(Object value, Long expire, Future future) {
			this.value = value;
			this.expirationTime = (expire == null ? null : System.currentTimeMillis() + expire);
			this.future = future;
		}

		/**
		 * Judging whether the entity is still alive
		 *
		 * @return boolean
		 */
		boolean isAlive() {
			return this.expirationTime == null || this.expirationTime >= System.currentTimeMillis();
		}
	}
}
  1. Java in Memory Cache – Geekout – From one propeller head to another!

彩蛋:

什么是 istio | Cizixs Write Here
【技术教程】利用User-agent-utils获取用户浏览器、操作系统等信息 - 数字人文技术实验室
新一代的微服务架构 Service Mesh - SegmentFault 思否
GitHub - qiao-zhi/Spring-Struts-Mybaits-Shiro: Spring+Struts2+Mybatis+Shiro的权限管理