在某些情况下我们需要使用本地缓存来加载一些小型数据,比如说一些配置数据。如果去查Mysql或者redis数据库需要走网络协议。这些数据可以加载到内存随时供Java程序调用。 接下来实现的是使用google的guava实现本地缓存,另外需要提供给其它服务使用的话,还可以使用netty对外发布服务,netty远程服务将会在接下来的本章中总结。 1、 策略接口,每个策略都必须实现这个标签的策略接口 ```java public interface ILocalCache { /** * 根据key获取value * @param k key * @return value */ V get(K k); /** * 设置k和v的值 * @param k * @param v */ void set(K k,V v); } ``` 2、 新建一个策略辅助类(封装了对Guava Cache的利用,包括cache的创建,从数据源获取数据,设置K,V等) ```java public abstract class GuavaAbstractCache { private int maximumSize = Integer.MAX_VALUE; // 最大缓存条目 private int expireAfterWriteDuration = 60*24; // 数据存在时长(一天) private TimeUnit timeUnit = TimeUnit.MINUTES; // 时间单位(分钟) private LoadingCache cache; /** * 通过调用getCache().get(key)来获取数据 * @return cache */ public LoadingCache getCache() { if (cache == null) { // 使用双重校验锁保证只有一个cache实例 synchronized (this) { if (cache == null) { cache = CacheBuilder.newBuilder() // 缓存数据的最大条目,也可以使用.maximumWeight(weight)代替 .maximumSize(maximumSize) // 数据被创建多久后被移除 默认设置一天 .expireAfterWrite(expireAfterWriteDuration, timeUnit) // 创建缓存使用fetchData .build(new CacheLoader() { @Override public V load(K key) throws Exception { return fetchData(key); } }); } } } return cache; } /** * 从缓存中获取数据(第一次自动调用fetchData从外部获取数据) * @param key * @return Value * @throws ExecutionException */ protected V getValue(K key) throws ExecutionException { V result = getCache().get(key); return result; } /** * 直接设置缓存数据到 * @param key * @param value */ protected void setValue(K key,V value) throws ExecutionException { getCache().put(key, value); } /** * 根据key从数据库或其他数据源中获取一个value, * 并被自动保存到缓存中。 这个方法由子类实现, * 以达到不同策略从不同的数据源获取缓存信息的效果 * @param key * @return value,连同key一起被加载到缓存中。 */ protected abstract V fetchData(K key); } ``` 3、 实现一个加载文件中的标签数据的缓存类 ```java public class TagsCache extends GuavaAbstractCache implements ILocalCache { public static final String TAGSKEY = "tags"; @Override public Object get(String k) { try { return getValue(k); } catch (Exception e) { return null; } } @Override public void set(String k, Object v) { try { setValue(k, v); } catch (Exception e) { e.printStackTrace(); } } @Override protected Object fetchData(String key) { //如果是tags标签数据直接从文件里加载,每天加载一次 if (TAGSKEY.equals(key)) { final File file = new File("/data/ids/tags.txt"); if(!file.exists()) { CommonLog.error("标签文件不存在"); return null; } final Set tagsSet = new HashSet(); FileInputStream inputStream = null; BufferedReader bufferedReader = null; try { inputStream = new FileInputStream(file); bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); String tag = ""; while ((tag = bufferedReader.readLine()) != null) { if(StringUtils.isNotEmpty(tag)) { tagsSet.add(tag); } } } catch (Exception e) { e.printStackTrace(); } finally { try { if (inputStream != null) { inputStream.close(); } } catch (IOException e) { e.printStackTrace(); } try { if (bufferedReader != null) { bufferedReader.close(); } } catch (IOException e) { e.printStackTrace(); } } return tagsSet; }else if("aaaa".equals(key)) { return "你好"; } return null; } public static void main(String[] args) { ILocalCache cache = new TagsCache(); System.out.println(cache.get("aaaa")); cache.set("aaaa", "nihao"); System.out.println(cache.get("aaaa")); System.out.println(cache.get("aaaa")); System.out.println(cache.get("aaaa")); System.out.println(cache.get("aaaa")); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(cache.get("aaaa")); System.out.println(cache.get("aaaa")); System.out.println(cache.get("aaaa")); System.out.println(cache.get("aaaa")); System.out.println(cache.get("aaaa")); } } ``` 4、 上面的main方法是设置缓存1秒钟过期的效果为: ``` 你好 nihao nihao nihao nihao 你好 你好 你好 你好 你好 ``` <ins class="adsbygoogle" style="display:block; text-align:center;" data-ad-layout="in-article" data-ad-format="fluid" data-ad-client="ca-pub-4353345653789615" data-ad-slot="8840342077"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({});</script>在某些情况下我们需要使用本地缓存来加载一些小型数据,比如说一些配置数据。如果去查Mysql或者re 你的当前访问异常,请进行认证后继续阅读剩余内容。 提交