Edited at

ConcurrentHashMapを利用したCache実装メモ

More than 5 years have passed since last update.

実装する度に迷うので、自分用実装パターンメモ。

cacheするものはそれぞれなので、ひとまず簡略化の為にnewInstance()にしています。throws Exceptionも簡略化のため…

※ 元はClass名.xmlをJAXB.unmarshal()したものをcacheするユーティリティ。

クラス名はRepository等も良いかもしれません。


Java 8

※ 初めてのJava 8


Registry.java

package cache.test;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

public class Registry {

private static final ConcurrentMap<String, Object> CACHE = new ConcurrentHashMap<>();

private Registry() {
}

public static Object load(final Class<?> clazz) throws Exception {
if (clazz == null) {
throw new IllegalArgumentException();
}
return CACHE.computeIfAbsent(clazz.getName(), key -> {
try {
return clazz.newInstance();
} catch (Exception e) {
throw new IllegalStateException(e);
}
});
}
}



Java 1.5 - 1.7

※ ダイヤモンド演算子は1.7以降


一般的(?)


Registry.java

package example;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

public class Registry {

private static final ConcurrentMap<String, Object> CACHE = new ConcurrentHashMap<>();

private Registry() {
}

public static Object load(final Class<?> clazz) throws Exception {
if (clazz == null) {
throw new IllegalArgumentException();
}
final String key = clazz.getName();
Object current = CACHE.get(key);
if (current != null) {
return current;
}
current = clazz.newInstance();
final Object anotherCached = CACHE.putIfAbsent(key, current);
if (anotherCached != null) {
return anotherCached;
}
return current;
}
}



R-STYLEの趣味


Registry.java

package example;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

public class Registry {

private static final ConcurrentMap<String, Object> CACHE = new ConcurrentHashMap<>();

private Registry() {
}

public static Object load(final Class<?> clazz) throws Exception {
if (clazz == null) {
throw new IllegalArgumentException();
}
final String key = clazz.getName();
if (CACHE.containsKey(key)) {
return CACHE.get(key);
}
final Object newOne = clazz.newInstance();
final Object anotherCached = CACHE.putIfAbsent(key, newOne);
if (anotherCached != null) {
return anotherCached;
}
return newOne;
}
}