代码之家  ›  专栏  ›  技术社区  ›  Alfred

从某个密钥查找消息,直到某个密钥,同时能够删除过时的密钥

  •  4
  • Alfred  · 技术社区  · 15 年前

    我的问题

    假设我希望将消息保存在某种类型的数据结构中,用于LongPolling应用程序:

    1. "dude"
    2. "where"
    3. "is"
    4. "my"
    5. "car"
    

    从索引[4,5]请求消息应返回: "my","car" .

    下一步,假设过一段时间后,我想清除旧邮件,因为它们不再有用,我想保存内存。我们说好了 x 消息[1-3]已过时。我认为每删除一次是最有效的 X 秒。接下来,我的数据结构应该包含:

    4. "my"
    5. "car"
    

    我的解决方案?

    我想用一个 concurrentskiplistset concurrentskiplist 地图。我也在考虑从一个 newSingleThreadScheduledExecutor . 我想知道您将如何实现(高效/线程安全)这个或使用一个库?

    2 回复  |  直到 15 年前
        1
  •  2
  •   Ed Gonzalez    15 年前

    在我看来,最大的问题是如何让某些元素在一段时间后过期。我有一个类似的需求,我创建了一个消息类,它实现了 Delayed Interface . 这个类包含了我需要的所有消息,并且(通过延迟的接口)在消息过期时告诉了我。

    我在并发集合中使用了此对象的实例,您可以使用 ConcurrentMap 因为它允许您用一个整型键为这些对象设置键。

    我每隔一次就收获一次收藏品,删除那些延迟已过的物品。我们使用延迟接口的getdelay方法测试过期:

    message.getDelay(TimeUnit.MILLISECONDS);
    

    我使用了一个正常的线程,它将休眠一段时间,然后获取过期的项目。在我的要求中,在物品延迟到期后立即移除并不重要。你似乎也有类似的灵活性。

    如果您需要在项目延迟到期后立即删除它们,那么您将在第一个到期的消息延迟时休眠,而不是在接收线程中休眠一个设置的时间段。

    这是我的延迟信息课程:

    class DelayedMessage implements Delayed {
    
        long endOfDelay;
        Date requestTime;
        String message;
    
        public DelayedMessage(String m, int delay) {
            requestTime = new Date();
            endOfDelay = System.currentTimeMillis()
                    + delay;
            this.message = m;
        }
    
        public long getDelay(TimeUnit unit) {
            long delay = unit.convert(
                    endOfDelay - System.currentTimeMillis(),
                    TimeUnit.MILLISECONDS);
            return delay;
        }
    
        public int compareTo(Delayed o) {
            DelayedMessage that = (DelayedMessage) o;
            if (this.endOfDelay < that.endOfDelay) {
                return -1;
    
            }
            if (this.endOfDelay > that.endOfDelay) {
                return 1;
            }
            return this.requestTime.compareTo(that.requestTime);
        }
    
        @Override
        public String toString() {
            return message;
        }
    }
    
        2
  •  2
  •   polygenelubricants    15 年前

    我不确定这是不是你想要的,但看起来你需要 NavigableMap<K,V> 对我来说。

    import java.util.*;
    public class NaviMap {
        public static void main(String[] args) {
            NavigableMap<Integer,String> nmap = new TreeMap<Integer,String>();
            nmap.put(1, "dude");
            nmap.put(2, "where");
            nmap.put(3, "is");
            nmap.put(4, "my");
            nmap.put(5, "car");
    
            System.out.println(nmap);
            // prints "{1=dude, 2=where, 3=is, 4=my, 5=car}"        
    
            System.out.println(nmap.subMap(4, true,  5, true).values());
            // prints "[my, car]"              ^inclusive^  
    
            nmap.subMap(1, true, 3, true).clear();
            System.out.println(nmap);
            // prints "{4=my, 5=car}"
    
            // wrap into synchronized SortedMap
            SortedMap<Integer,String> ssmap =Collections.synchronizedSortedMap(nmap);
    
            System.out.println(ssmap.subMap(4, 5));
            // prints "{4=my}"                 ^exclusive upper bound!
    
            System.out.println(ssmap.subMap(4, 5+1));
            // prints "{4=my, 5=car}"          ^ugly but "works"
        }
    }
    

    现在, 不幸地 要得到一个 synchronized 版本A navigablemap<k,v> 但A SortedMap 确实有 subMap ,但只有一个上界严格排他的重载。

    API链接

    推荐文章