欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

用ConcurrentHashMap作缓存

程序员文章站 2022-06-28 16:31:29
// 用map实现一个简单的缓存功能public class MapCacheDemo { // 我使用了 ConcurrentHashMap,线程安全的要求。 //我使用SoftReference 作为映射值,因为软引用可以保证在抛出OutOfMemory之前,如果缺少内存,将删除引用的对象。 //在构造函数中,我创建了一个守护程序线程,每5秒扫描一次并清理过期的对象。 private static final int CLEAN_UP_PERIOD_IN_SE....
// 用map实现一个简单的缓存功能
public class MapCacheDemo {

    // 我使用了  ConcurrentHashMap,线程安全的要求。
    //我使用SoftReference   作为映射值,因为软引用可以保证在抛出OutOfMemory之前,如果缺少内存,将删除引用的对象。
    //在构造函数中,我创建了一个守护程序线程,每5秒扫描一次并清理过期的对象。
    private static final int CLEAN_UP_PERIOD_IN_SEC = 5;

  private static ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(1);
  private final ConcurrentHashMap<String, SoftReference<CacheObject>> cache = new ConcurrentHashMap<>();

    public MapCacheDemo() {
        scheduledThreadPoolExecutor.setThreadFactory(new ThreadFactoryBuilder()
                .setNameFormat("demo-pool-%d").build());
        scheduledThreadPoolExecutor.scheduleAtFixedRate(()->cache.entrySet().removeIf(entry -> Optional.ofNullable(entry.getValue()).map(SoftReference::get).map(CacheObject::isExpired).orElse(false)),
                5,5,TimeUnit.SECONDS);
    }

    public void add(String key, Object value, long periodInMillis) {
        if (key == null) {
            return;
        }
        if (value == null) {
            cache.remove(key);
        } else {
            long expiryTime = System.currentTimeMillis() + periodInMillis;
            cache.put(key, new SoftReference<>(new CacheObject(value, expiryTime)));
        }
    }

    public void remove(String key) {
        cache.remove(key);
    }

    public Object get(String key) {
        return Optional.ofNullable(cache.get(key)).map(SoftReference::get).filter(cacheObject -> !cacheObject.isExpired()).map(CacheObject::getValue).orElse(null);
    }

    public void clear() {
        cache.clear();
    }

    public long size() {
        return cache.entrySet().stream().filter(entry -> Optional.ofNullable(entry.getValue()).map(SoftReference::get).map(cacheObject -> !cacheObject.isExpired()).orElse(false)).count();
    }

    // 缓存对象value
    private static class CacheObject {
        private Object value;
        private long expiryTime;

        private CacheObject(Object value, long expiryTime) {
            this.value = value;
            this.expiryTime = expiryTime;
        }

        boolean isExpired() {
            return System.currentTimeMillis() > expiryTime;
        }

        public Object getValue() {
            return value;
        }

        public void setValue(Object value) {
            this.value = value;
        }
    }
}

 

本文地址:https://blog.csdn.net/xx897115293/article/details/110263299

相关标签: 缓存