我必须使用 ehache 2(用 2.9.0 和 2.10.4 测试)和SelfPopulatingCache
. 如果我overflowToDisk="true"
在ehcache.xml
. 不写入硬盘,一切都很好。
在开始输出总是:
...
Key creating (hello) 0
Refresh
...
大约 50 次刷新后,输出变为:
...
Refresh
...
原因是方法getKeys()
上的refresh()
方法返回一个空集合。
例子
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true"
monitoring="autodetect" dynamicConfig="true">
<diskStore path="./target" />
<cache name="cache1"
maxEntriesLocalHeap="100"
maxElementsOnDisk="1000"
eternal="false"
timeToIdleSeconds="3600"
timeToLiveSeconds="3600"
memoryStoreEvictionPolicy="LFU"
transactionalMode="off"
diskPersistent="false"
overflowToDisk="true"
>
</cache>
</ehcache>
import java.util.ArrayList;
import java.util.List;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Element;
import net.sf.ehcache.constructs.blocking.CacheEntryFactory;
import net.sf.ehcache.constructs.blocking.SelfPopulatingCache;
public class StartSimple {
private static final int TEST_THREADS = 1;
private static final int LOOPS = 1_000_000_000;
private static class Value {
public Value(String value) {
this.value = value;
}
public String value;
@Override
public String toString() {
return value;
}
}
public static class MyCacheEntryFactory implements CacheEntryFactory {
int i = 0;
@Override
public Object createEntry(Object key) throws Exception {
System.out.println("Key creating (" + key + ") " + i);
return new Value((String) key + i++);
}
}
public static class RunningChild implements Runnable {
Ehcache cache;
public RunningChild(Ehcache cache) {
this.cache = cache;
}
@Override
public void run() {
for (int i = 0; i < LOOPS; i++) {
if (!cache.get("hello").getObjectValue().toString().startsWith("hello")) {
throw new IllegalStateException();
}
}
}
}
public static class Refresh implements Runnable {
SelfPopulatingCache cache;
boolean running;
public Refresh(SelfPopulatingCache cache) {
this.cache = cache;
this.running = true;
}
@Override
public void run() {
while (running) {
cache.refresh(true);
System.out.println("Refresh");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
System.err.println("Error " + e.getMessage());
}
}
}
}
public static void main(String[] args) throws InterruptedException {
CacheManager cm = CacheManager.getInstance();
Ehcache parentCache1 = cm.getCache("cache1");
SelfPopulatingCache cache = new SelfPopulatingCache(parentCache1, new MyCacheEntryFactory());
// add one element
cache.put(new Element("hello", new Value("hello")));
// create test threads
final List<Thread> threads = new ArrayList<>();
for (int i = 0; i < TEST_THREADS; i++) {
Thread t = new Thread(new RunningChild(cache));
threads.add(t);
}
// create refresh thread
Refresh refresh = new Refresh(cache);
Thread refreshThread = new Thread(refresh);
refreshThread.setPriority(Thread.MAX_PRIORITY);
refreshThread.start();
long start = System.currentTimeMillis();
// start runner threads and wait for end
for (final Thread t : threads) {
t.start();
}
for (final Thread t : threads) {
t.join();
}
long end = System.currentTimeMillis();
// waiting for end - refresh thread
refresh.running = false;
refreshThread.join();
System.out.println(cache.get("hello"));
System.out.println((end - start) + " ms");
System.out.println("End");
}
}