LinkedHashMap有趣用法

最近在做网关时候,需要对请求url做一个规范验证,当不符合规范时候,自动邮件报警给系统负责人。邮件报警处理方式见https://blog.csdn.net/lengyue309/article/details/97021272。

功能做好了,发布到测试环境,过了半天邮箱爆炸了,收到一段的url规范邮件,全是重复的,只要请求一次邮件就发送一次。于是就想如何减少重复发送邮件?用队列?用redis?google工具包的本地缓存?虽然都能实现,但总感觉给系统带来复杂性。

最简单方式还是直接放内存,同时又能满足一下要求:

  1. 同一个url一天只发送一次
  2. 数量要有一个限制,防止内存爆炸
  3. 超过最大限制时候,抛弃最老那个值

于是就想到了LinkedHashMap,直接附上用法:

private static Map map = new LinkedHashMap() {
        private static final long serialVersionUID = 6918023506928428613L;
        private int MAX_ENTRIES = 1000;

        // 如果Map的尺寸大于设定的最大长度,返回true,再新加入对象时删除最老的对象
        @Override
        protected boolean removeEldestEntry(Map.Entry eldest) {
            return size() > MAX_ENTRIES;
        }
    };

然后再使用地方做一个简单判断即可:

// true发送邮件,同一个url1天只发送一次
    private boolean email(String uri) {
        if (uri.matches(REGEX)) {
            return false;
        }

        String date = format.format(new Date());
        String keyvalue = map.get(uri);
        if (StringUtils.isBlank(keyvalue)) {
            map.put(uri, date);
            return true;
        }

        if (keyvalue.equals(date)) {
            return false;
        }

        map.put(uri, date);
        return true;
    }

如果考虑线程安全问题,推荐大家使用ConcurrentLinkedHashMap类。只需要引入下面包:


            com.googlecode.concurrentlinkedhashmap
            concurrentlinkedhashmap-lru
            1.4
        

代码如下:

/**
     * ConcurrentLinkedHashMap 可以做并发操作。 超过1000会删除最老的数据
     */
    private static ConcurrentLinkedHashMap map = new ConcurrentLinkedHashMap.Builder()
            .maximumWeightedCapacity(1000).weigher(Weighers.singleton()).build();

 

你可能感兴趣的:(java)