2017-04-04 1 views
2

내가 예에 대한 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

클라이언트에서 데이터를 전송할 때 데이터를 어떻게 선언합니까? 데이터가 무엇인지 알면 클라이언트에서 가져올 필요가 없습니다. 요청하지 않으면 데이터를 캡처하지 않아도됩니다. –

답변

0

첫 번째 솔루션은 들어오는 요청마다 배열이 복사되므로 성능 문제가 발생할 수 있습니다.

세 번째 해법이 더 좋습니다. 내재 된 잠금은 컨트롤러/서비스의 정적 개체이기도합니다. 이것은 또한 data을 만질 때마다 싱크로 나이 제이션 된 블록을 기억할 필요가 있으므로 아마도 이것도 최선의 해결책이 아닙니다.

두 번째 옵션은이 사건에 대한 최선의 해결책입니다. 내부적으로 data을 저장하는 싱글 톤을 생성하고 synchronized 방법을 제공하십시오. 동기화 물건은 하나의 클래스 안에서 닫힙니다.

//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()를 사용할 수 있습니다 좋아하는 싱글 래퍼의 구현에

내 시도는 것 같습니다.

참고 수집 된 데이터로 어떻게 게임 할 지 모르지만 목록 이외의 다른 컬렉션을 고려해보십시오. 특정 데이터 발생 횟수가 중요하지 않은 경우 ListSetHashSet 구현으로 대체하는 것이 좋습니다. (당신이 data=test1을 두 번 받았을 때와 마찬가지로 몇 번이나 test1이 마음에 든다면). 숫자를 신경 쓰면 값의지도를 발생 횟수로 간주 할 수도 있습니다.

0

내가는 HashMap을 사용하여 서비스에

public boolean addKey(String key, String value); 

그런 방법으로 싱글 서비스를 사용합니다>

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

질문의 핵심은 스레드 안전이었으며 스레드 안전하지 않은 솔루션을 제공했습니다. Btw. 열쇠 란 무엇이며 가치는 무엇입니까? –

+0

아, 죄송합니다. add 키워드와 getKeyMap 메서드에 synchronized 키워드를 추가하기 만하면됩니다. – cralfaro

+0

그들은 열쇠가 "데이터"매개 변수가 될 것이고, 목록은 당신의 모든 매개 변수 값을 test1, test2, ...로 저장할 것입니다. – cralfaro