2011-08-03 2 views
1

수신 된 요청과 응답을 추적하는 메커니즘으로 참조 계산을 사용하는 응용 프로그램 컨테이너에서 작업하고 있습니다. 참조 카운트는 컨테이너의 정상적인 종료를 허용하는 데 사용됩니다. 즉, if (refCount == 0) shutdown;은 좋은 디자인을 참조하는 참조입니다.

참조 횟수는 모든 요청과 보류중인 응답에 대해 증가합니다. 참조 횟수는 응용 프로그램이 요청을 수락하고 응용 프로그램이 유효한 응답을 보낸 후에 만 ​​감소합니다. 그래서 내 질문은이 응용 프로그램/컨테이너가 응답을 보낼 때만 닫힌 RequestContext을 유지하는 것과 비교하여이 시나리오에서 참조가 좋은 디자인 결정을 세는 것인가?

소프트웨어가 Java로 구현 되었기 때문에 나는 Java의 다른 옵션을보고이 문서 전체를 보았습니다. http://weblogs.java.net/blog/2006/05/04/understanding-weak-references이 나와서 ReferenceQueue을 활용하려고 시도하는 것이 다른 방법 일 수 있다고 생각했습니다.

+5

여기에 "참조 계산"이라는 용어가 오버로드되어 있다고 생각합니다. 요청 개체를 새 참조에 할당하면 참조 횟수가 증가하지 않습니다. 맞습니까? 나는 여기서 "참조"가 모든 용어에 속한다고 생각하지 않는다. –

답변

1

실제로는 정말 깔끔한 방법입니다. ThreadLocal도 추가로 사용해야합니다 (요청 - 응답 파이프 라인이 단일 스레드로 처리되는 경우)

기본적으로 요청을 받으면. WeakRefernce를 사용하여 ThreadLocal을 요청 객체 (또는 요청의 일부 속성 (예 : 사용자 ID 등))로 설정합니다. 그런 다음 처리 파이프 라인 내의 어느 곳에서나 객체를 get() 수 있습니다.

요청을 처리하기 위해 ThreadPool 작업자를 사용하는 경우 해당 개체에 대한 참조가 더 이상 존재하지 않도록 스레드의 ThreadLocal에서 약한 참조 개체의 설정을 해제해야합니다. 각 요청에 대해 새 스레드를 생성하는 경우이를 수행 할 필요조차 없습니다. 스레드가 죽으면 개체는 자동으로 referenceQueue로 반환됩니다 (해당 개체에 대한 라이브 참조가 없으므로)

+0

"ThreadLocal (요청 - 응답 파이프 라인이 단일 스레드로 처리되는 경우)을 추가적으로 사용해야합니다." 컨테이너가 단일 스레드라는 것을 분명히하십시오. 그렇다면 ThreadLocal을 사용하면 실제로 CPU 사이클이 낭비됩니다. – alphazero

+0

오 절대적으로 .. 나는 다중 스레드 컨테이너에 대해 이야기하고 있었다. 내 말씨가 잘못 이해 한 것을 용서해주십시오. –

+0

설명해 주셔서 감사합니다. 너를 오해해서 나를 용서해! – alphazero

1

성능 히트를 가진 카운터에 대해 비용을 지불하게됩니다. 사실상 요청을 처리하기 위해 동시 스레드를 사용하고있는 모든 요청 IFF에 대해 메모리 장벽이 필요합니다. (메모리 장벽 명령은 일반적으로 ~ 200 개의 명령까지 비용이 많이 든다.)

귀하의 질문에 더하여, 카운터를 원하지는 않지만 오히려 활성 요청이 있는지를 나타내는 바이너리 플래그가 있습니다. requestsInProgress 플래그. 그 아이디어는 깃발 값이 false 일 때 '정상 종료'하는 것입니다.

귀하의 컨테이너가 주로 네트워크 종점을 노출하는 경우. REST/HTTP를 사용하면 NIO를 고려하고 컨테이너 주변에서 req/rep를 선형화하는 단일 스레드 디스패치 메커니즘을 사용하는 것이 좋습니다. (당신은 java.util.concurrent에 동시 큐를 사용하여 N 처리 스레드 밖으로 이들과 팬을 대기 할 수

[NIO subsystem] <-{poll}-[Selector(accept/read)/dispatch thread] => [Q:producer/consumer pattern 1:N] 
[NIO subystem] <-{poll}-[Selector(write)/responder thread] <= [Q:producer/consumer N:1] 

혜택

당신이 파견 및 응답 후 더 메모리 장벽이 포함되지 않습니다에 대한 동일한 스레드를 사용하는 경우 -.?를 스레드가 코어에 고정되고 깃발이 캐시 라인 전용입니다 :

예 :파견 큐 후

는 요청 : 증가 req_in_progress

응답자를 꺼내 응답 후 : 감소 req_in_progress

가 종료에 공유 메모리 동기화에 대한 필요성이 될 볼 수 있지만, 그 비용을 들이지보다 훨씬 더 나은 것 각각의 요청마다, 실제로 필요할 때만 비용을 지불하십시오.

성능에 전혀 문제가 없다면 카운터에 AtomicInteger을 사용하고 글로벌 컨텍스트에 넣는 것이 어떻습니까?

관련 문제