如何在init期间为LinkedHashMap removeEldestEntry导入提供自定义函数

时间:2018-06-14 18:17:06

标签: java

考虑这个初始化

    this.cache = new LinkedHashMap<K, V>(MAX_ENTRIES+1, .75F, true) {
        public boolean removeEldestEntry(Map.Entry eldest) {           
        }
    };

有没有办法用从另一个类导入的定义替换removeEldestEntry

我想这样做的原因是因为我有一个包含executorcache的通用包装类,但对于不同的可运行任务,cache存储不同的信息,因此需要LinkedHashMap.removeEldestEntry

的不同行为

编辑:

public class MyBufferService<K, V> {

    private ThreadPoolExecutor executor;
    private final Map cache;

    public MyBufferService(String buffName) {
        executor = new ThreadPoolExecutor(1, // corePoolSize
                1, // maximumPoolSize
                60, TimeUnit.SECONDS, // keepAlive
                new LinkedBlockingQueue<>(10000), // workQueue
                new ThreadFactoryBuilder().setNameFormat(buffName + "-MyBufferService-thread-%d").build(), // factory
                new ThreadPoolExecutor.CallerRunsPolicy() // rejected execution handler
        );

        this.cache = new LinkedHashMap<K, V>(1000, .75F, true) {
            public boolean removeEldestEntry(Map.Entry eldest) {
            }
        };
    }
}

在上面的代码中,executor接受任何实现runnable的类,因此假设您有两个任务,即runnable,每个人都希望提供自己的removeEldestEntry功能由线程池执行。

有没有办法实现这个目标?

编辑2:

    private class BufferTask implements Runnable {

        private final String mystring;
        private final Map cache;

        BufferTask(String mystring, Map cache) throws NullPointerException {
            this.mystring = mystring;
            this.cache = cache;
        }
        @Override
        public void run() {
            try {
                synchronized (this.cache) {
                    this.cache.put(this.mystring, "hi");
                }
            } catch (Throwable t) {
            }
        }
        public boolean removeEldestEntry(Map.Entry eldest) {
        }
    }

目标实际上是让每种类型的任务都提供自己的removeEldestEntry

编辑3:

以下是我提交任务的方式

public class BufferService<K, V>{

    public BufferService(String bufferName) {
        executor = new ThreadPoolExecutor(1, // corePoolSize
            1, // maximumPoolSize
            keepAliveTimeSec, TimeUnit.SECONDS, // keepAlive
            new LinkedBlockingQueue<>(queueSize), // workQueue
            new ThreadFactoryBuilder().setNameFormat(bufferName + "-KafkaBufferService-thread-%d").build(), // factory
            new ThreadPoolExecutor.CallerRunsPolicy() // rejected execution handler
        );

        this.cache = new LinkedHashMap<K, V>(MAX_ENTRIES+1, .75F, true) {
             public boolean removeEldestEntry(Map.Entry eldest) {
             }
        };
    }

    public void putDeferBufferTask(
            String myString) throws RejectedExecutionException, NullPointerException {
        executor.submit(new BufferTask(myString, this.cache));
    }

}

1 个答案:

答案 0 :(得分:0)

如果我理解您的问题,您要搜索的内容可能是策略模式。这样你就可以注入任何行为。

public MyBufferService(String buffName, Predicate<Map.Entry> removeEldestEntryImplementation) {
    ... 
    this.cache = new LinkedHashMap<K, V>(1000, .75F, true) {
        public boolean removeEldestEntry(Map.Entry eldest) {
            return removeEldestEntryImplementation.test(eldest);
        }
    };
}

不要对方法名test()感到困惑,我只是使用标准库提供的标准功能接口Predicate,它具有合适的签名。

按照编辑2,您可以像这样加入:

private class BufferTask implements Runnable, Predicate<Map.Entry> {
    ....
    private boolean removeEldestEntry(Map.Entry eldest) {
        // your mysterious code here
    }
    @Override
    public boolean test(Map.Entry eldest) {
        return removeEldestEntry(eldest);
    }
}

然后将此类的实例传递给MyBufferService的构造函数。