2016-07-12 2 views
0

모든 리소스에 대한 기본 경로가있는 파일이 있습니다. 예를 들어 :코드로 경쟁 조건이 생성됩니까?

내가 할 바라고 무엇
https://example.org/SuperDuperSite/build/scripts/script1.js 

경로와 시작시 글로벌 사전에 파일을로드했습니다 : 물론

build/scripts/script1.js 
build/scripts/script2.js 

나는 예를 들어 기본 경로가 필요합니다. 사전은 한 번만로드하면됩니다. 불행히도, 내가 말할 수있는 한 기본 경로는 첫 번째 요청 때까지 사용할 수 없습니다. 그래서 asp.net에서 application_start보다는 application_beginrequest을 사용해야합니다. 이 점에 대해 나쁘다는 것이 이제는 멀티 스레딩 문제를 다루어야 만합니다. 난 단지 정말 한 번을로드 할 때

lock(_lock) { 
    if (_dictionary == null) { 
     LoadDictionary(); 
    } 
    } 

이것은 모든 단일 요청에 대해 호출 할 것이다 : 저를 강제로

코드의 다음과 같은 유형을 작성합니다. 나는이 사실을 정말로 좋아하지 않는다. 성능상의 이유로 모든 요청을 잠글 필요가 없습니다. 한 가지 해결책은, 대학 이야기 후 우리가 해낸 것을 : 나는 모든 단일 요청에 잠글 필요하지 않을 것입니다이 솔루션 그래서

if (_dictionary == null) 
{ 
    lock(_lock) { 
     if (_dictionary == null) { 
     LoadDictionary(); 
     } 
    } 
} 

하지만 여러 스레드가 시작시이 부분을 받고 결국 있다면 나는 그 보호 할 수 객체가 자물쇠 안에 다시 있는지 검사하여 이 코드가 작동할까요, 아니면 경쟁 조건에 부딪 힐까요?

+0

기본 URL을 포함하는 데 많은 복잡성이 있습니다. 시작할 때 사전에로드하는 경로를 결정한 이유가 있습니까? –

+1

당신은 이것을 올바른 각도에서 공격하고 있습니까? 상대 경로 요청을 할 수없는 이유가 있습니까? –

+1

C#에서는 이중 잠금이 안전합니다.코드 샘플의 조건은 역순이지만 다른 괜찮습니다. –

답변

1

이중 확인 잠금을 사용할 때주의하십시오.

네, 스레드 안전하지만 에 특정 코드 당신이 이 다른 스레드합니다 (null 검사를 통과)에 의해을 인스턴스화 _dictionary가되었습니다 미묘한 버그로 실행할 수도 있지만 완전히 아직을 채워 , 부분적으로 채워진 사전에 액세스하려고 시도 할 수도 있습니다. 사전을 읽을 때 당신은 결과를 놓치고

  1. , 또는 더 나쁜
  2. 당신이이 ConcurrentDictionary (또한 성능에 영향와 함께 제공되는), 당신은 할 수 사용하지 않는 : 그리고이 두 가지 중 하나와 끝까지 사전에 동시에 읽고 읽고 쓸 수 있으며 교착 상태가 발생합니다 (예 : Dictionary 클래스는 많은 코드에서 교착 상태를 일으키는 것으로 알려져 있음).

(더블 - 확인), LoadDictionary()의 말에 true에 이성을 상실 bool _dictionaryLoaded 플래그 A는 아마 더 좋다.

.NET 4를 사용하는 경우 Lazy<>을 사용하십시오. 훨씬 더 깨끗합니다. LoadDictionary을 초기화 기능으로 사용하면됩니다.

편집 : Lazy <>은 internally implemented with a double-checked lock입니다.

관련 문제