All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.javaoffers.batis.modelhelper.utils.SoftCache Maven / Gradle / Ivy

There is a newer version: 3.5.11.12
Show newest version
package com.javaoffers.batis.modelhelper.utils;

import javafx.util.Pair;

import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * Released by GC when memory is not enough
 * @author mingJie
 */
public class SoftCache implements Runnable{

    private static int limitMi = 1 << 11;

    // soft ref
    private ReferenceQueue referenceQueue;

    //cache
    private volatile Map> cache = new ConcurrentHashMap<>(1 << 8);

    // new install of SoftCache
    public static  SoftCache getInstance(){

        SoftCache softCache = new SoftCache();
        softCache.referenceQueue = new ReferenceQueue<>();
        CommonExecutor.oneFixedScheduledThreadPool.scheduleWithFixedDelay(softCache, 60, 60, TimeUnit.SECONDS);
        return softCache;
    }

    public void put(T key, V value){
        //key = null;
        if(key == null || value == null){return;}
        SoftData softData = new SoftData(key, value, this.referenceQueue);
        cache.put(key, softData);
    }

    public V get(T key){
        //key = null;
        if(key == null){
            return null;
        }
        SoftData softData = cache.get(key);
        if(softData != null){
            V value = softData.get();
            if(value != null){
                return value;
            }else{
                //clear outdated
                cache.remove(key);
            }
        }
        return null;
    }

    @Override
    public void run() {
        try {
            long mk = Runtime.getRuntime().freeMemory() >> 20;
            AtomicBoolean statue = new AtomicBoolean(false);
            if(limitMi < mk){
                Map> newCache = new ConcurrentHashMap<>(1 << 8);
                this.cache.forEach((key,value)->{
                    if(value.get() != null){
                        newCache.put(key, value);
                    }else{
                        statue.set(true);
                    }
                });

                if(statue.get()) {
                    this.cache = newCache;
                    this.referenceQueue = new ReferenceQueue<>();
                }

            }else{
                this.cache.forEach((key,value)->{
                    if(value.get() == null){
                        this.cache.remove(key);
                        statue.set(true);
                    }
                });
                if(statue.get()) {
                    this.referenceQueue = new ReferenceQueue<>();
                }
            }
        }catch (Exception e){
            //ignore
        }
    }

    static class SoftData extends SoftReference {
        T key;
        public SoftData(T key,V value,ReferenceQueue referenceQueue) {
            super(value, referenceQueue);
            this.key = key;
        }
    }

    private SoftCache(){ }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy