我怎样才能捕捉请求数据在静态列表

问题描述:

我有用于如URL:我怎样才能捕捉请求数据在静态列表

http://some_url.suffix?data=test1. 

我将有排序的多个请求:

http://some_url.suffix?data=test1 
http://some_url.suffix?data=test2 
http://some_url.suffix?data=test3 
http://some_url.suffix?data=test4 

我希望保持服务器端的静态列表,其中将包含从所有会话请求接收的数据

List<String> data; 

列表将包含data1,d ATA2,DATA3,DATA4。列表将在特定时间间隔后被清除,新列表将用于后续请求。 什么是实现这一目标的最佳选择:

1. static List<String> data = new CopyOnWriteArrayList<String>(); 
2. Singleton wrapper class to perform operation on normal java.util.List 
3. using synchronized block 
+0

'data.add(request.getParameter('data'))'? –

+0

这是很明显的,但我想知道最好的方式,即静态声明的数据或其他东西。 – dpanshu

+0

如何从客户端发送数据时声明数据?如果您知道数据是什么,则无需从客户端获取数据,如果您不知道该数据,则必须从请求中获取数据。 –

第一种解决方案可能会导致性能问题,因为数组将在每个传入请求上被复制。

第三种解决方案比较好,只要记住固有锁应该也是控制器/服务上的静态对象。这也需要每次触摸data时记住同步块,因此这可能不是最佳解决方案。

第二种选择是针对该情况的最佳解决方案。创建内部存储data的单身人士,并提供​​方法来玩它。同步内容将在一个类中关闭。

我试图实现,单包装的将是这样的:

//Use enum to have singleton provided by jvm 
enum DataCache { 

    INSTANCE; 

    //Use LinkedList if you expecting many calls. The insertion will be much faster. 
    private List<String> data = new LinkedList<>(); 

    synchronized void add(String value) { 
     data.add(value); 
    } 

    /* 
    * Returns defensive copy, so that no one has reference to this.data. 
    * If data is fetched only on clear you can make this private instead of synchronized 
    * (or even better get rid of it and create defensive copy inside clear()). 
    */ 
    synchronized List<String> get() { 
     return new ArrayList<>(data); 
    } 

    /* 
    * Returns last snapshot of data to keep consistency. 
    */ 
    synchronized List<String> clear() { 
     List<String> lastSnapshot = get(); 
     data = new LinkedList<>(); 
     return lastSnapshot; 
    } 
} 

然后你就可以在该处理的调度请求,并INSTANCE.clear()方法使用INSTANCE.add()

注意我不知道你如何玩收集的数据,但考虑其他收集比列表。如果特定数据事件的数量并不重要,则最好将List替换为SetHashSet的实现。 (就像你两次收到data=test1一样,你只关心测试1出现了多少次)。如果你关心数字,你也可以考虑将数值映射到出现次数。

我会用一个单独服务与方法

public boolean addKey(String key, String value); 

然后在你的服务,我会用一个HashMap>

private static Map<String, List<String>> keysMap; 

private Map<String, List<String>> getKeysMap(){ 
    synchronized (this){   
     if(keysMap == null){ 
      keysMap = new HashMap(); 
     } 
     return keysMap; 
    } 
} 

public void addKey(String key, String value){ 
    List<String> keyParams = getKeysMap().get(key); 
    if(keyParams == null){ 
     keyParams = new ArrayList(); 
    } 
    //decide here if you want to store repeated values 
    keyParams.add(param); 
    getKeysMap().put(key, keyParams); 
} 
+0

问题的全部内容是线程安全的,您提供的解决方案根本不是线程安全的。顺便说一句。什么是关键,什么是价值? –

+0

啊对不起,我忘记了,你只需要添加synchronized关键字添加方法和getKeyMap。 – cralfaro

+0

它们的键将是你的“数据”参数,并且该列表将存储所有你的参数值test1,test2,... – cralfaro