0

我必须使用 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");
    }

}
4

0 回答 0