2017-04-14 4 views
1

내가 뭘 하려는지 생각해 보자.
나는 많은 통계를 기록하는 프로그램을 가지고있다. 그들은 한 번에 하나의 일이로를 기록하고, 예를 들어, ArrayList에로두고 :
내가 이러한 통계를 기록하고 있지 않다,이 예입니다 유의하시기 바랍니다, 난 그냥 조금처리하기 전에 일정량의 대기열을 만들어 보자.

User clicks -> Add user_click to array
을 단순화하고 있습니다 User clicks -> Add user_click to array
Key press -> Add key_press to array

각 이벤트 이후

(클릭, 키 누름 등)이이 경우> 150 이하가 일어나는 ArrayList의 크기를 확인 :
새로운 스레드는 그 스레드가 ArrayList에 복사본을 부여
를 생성
새 스레드가 유사한 항목을 결합하므로 user_click이 수량 1의 항목 2 개 대신 각각 1 개가됩니다
스레드가 데이터를 MySQL 데이터베이스

이 방법이 더 효과적이지만, 더 나은 접근 방법을 찾고 싶습니다. 쓰래드 풀과 처리의 문제는 문자 그대로 수천 개의 MySQL 질의가 처음에는 결합되지 않는다는 것입니다.

더 좋은 방법이 있습니까? 내 방법 괜찮아?
염두에 두어야 할 다른 점은 events이 실행되고 기록되는 스레드가 느려질 수 없으므로 주 스레드의 항목을 결합하고 싶지 않은 스레드입니다.

위대한 코드 예제가있는 경우이를 수행하는 좋은 방법이 아니라면 멋진 코드 일 것입니다. 관심있는 사람들을위한

는,이 프로젝트가 GitHub의에서 호스팅되는, 메인 스레드가 here이며, 큐 프로세서는 here하고 불쌍한 내 이름 지정 규칙 및 일반 코드 청결, 난 여전히 해요 (항상) 학습을 용서하십시오!

+0

'Collection'이 특정 크기에 도달했을 때 Observer 패턴을 사용하여 알려야합니다. –

+0

ArrayList 대신 해시 맵에서 이벤트를 통합 할 수 있습니다. – SpiderPig

답변

5

설명하는 논리는 두 가지 조정과 함께, 꽤 좋은 것 같다

  • 목록을 복사하고 원본을 삭제하지 마십시오. 원본을 보내고 이후 이벤트를위한 새로운 목록을 만듭니다. 이렇게하면 O (n) 항목을 복사하는 처리 시간이 필요하지 않습니다.

  • 매번 새 스레드를 만들지 마십시오. 어쨌든 이벤트는 수집되므로 이벤트가 지연되므로 데이터베이스에 쓰는 시간을 중요시하지 않습니다. 두 가지 선택 :

    • 다음 스레드 2 뒤에 떨어지는 경우, 목록 스레드 2 수있을 때까지 큐에 누적 간단합니다 2. 스레드에 스레드 1에서 목록을 보낼 BlockingQueue를 사용, 정면 단일 스레드를 시작

      스레드 1을 지연시키지 않고 시스템에 과부하가 걸리지 않고 따라 잡으십시오.

    • 작업을 스레드 풀에 제출하십시오. Executor을 사용하십시오. 이렇게하면 처리가 이벤트 생성보다 느린 경우 다중 (그러나 제한된 수의) 스레드가 목록을 처리 할 수 ​​있습니다.단점은 이벤트가 순서가 맞지 않게 작성 될 수 있다는 것입니다.

      separation of concern 및 재사용의 목적

, 당신은 오히려 것을 필요없이, 별도의 클래스에서 처리 에 대한 블록에서 스레드 이벤트를 수집하고이를 전송의 논리을 캡슐화한다 이벤트 생성 코드에서 로직 에 임베드됩니다.

이렇게하면 쉽게 추가 기능을 추가 할 수 있습니다. 보류중인 이벤트를 정상 임계 값 (150)에 도달하기 전에 플러시하는 시간 초과로 인해 이벤트 생성이 느려지면 이벤트가 너무 오래 앉아 있지 않습니다.