문제

이것 블로그 게시물 문자열 ID 관용구 당 뮤텍스를 구현하는 방법을 보여줍니다. 사용 된 문자열 ID는 httpsession ID를 나타내는 것입니다.

  1. 왜 우리는 Mutex 인스턴스 주변에서 약한 회의를 포장해야합니까? String-> mutex에서 맵을 만드는 것이 낫지 않습니까?
  2. 왜 우리는 두 번 풋을 전화해야합니까?

    public Mutex getMutex( String id )
    {                                  
        Mutex key = new MutexImpl( id );
        synchronized( mutexMap )
        {
            WeakReference<Mutex> ref = mutexMap.get( key );
            if( ref == null )
            {
                mutexMap.put( key, new WeakReference<Mutex>( key ) );
                return key;
            }
            Mutex mutex = ref.get();
            if( mutex == null )
            {
                mutexMap.put( key, new WeakReference<Mutex>( key ) );
                return key;
            }
            return mutex;
        }
    }
    
도움이 되었습니까?

해결책

고리 그리고 브루노 콘데 거의 다루었지만 그 코드를 썼기 때문에 ...

설계 목표는 사용자가 릴리스 메커니즘을 호출하지 않도록하는 것이 었습니다. Mutex는 더 이상 참조하지 않을 때 쓰레기 수집을받을 수 있습니다.

왜 우리는 Mutex 인스턴스 주변에서 약한 회의를 포장해야합니까?

지도는 a입니다 약한 하슈 맵:

private final Map mutexMap = new WeakHashMap();

이 맵은 Mutex에 대한 참조를 유지하는 데 사용되지만 키와 값에 동일한 객체를 사용하는 경우 객체는 쓰레기 수집에 적합하지 않습니다. Javadoc :

구현 참고 : 약한 하슈 맵의 값 객체는 일반적인 강력한 참조로 보류됩니다. 따라서 값 객체가 키가 버려지는 것을 막기 때문에 값 객체가 직간접 적으로 자신의 키를 강력하게 언급하지 않도록주의를 기울여야합니다. 값 객체는 약한 해쉬 맵 자체를 통해 간접적으로 키를 참조 할 수 있습니다. 즉, 값 객체는 관련 값 객체가 첫 번째 값 객체의 키를 강력하게 지칭하는 다른 키 객체를 강력하게 지칭 할 수 있습니다. 이것을 다루는 한 가지 방법은 다음과 같이 삽입하기 전에 약한 차지 내에서 값을 스스로 랩핑하는 것입니다. m.put (key, new weecreference (value)), 각 get에 랩핑을 풀는 것입니다.


String-> mutex에서 맵을 만드는 것이 낫지 않습니까?

그 문자열 값은 언제 쓰레기를 수집합니까? 매번 동일한 참조가 통과됩니까? 가지다 인턴() 그것에 부름 받았어? 인턴에 전화하면 끈이 얼마나 오래 살 수 있습니까? 문자열이 열쇠 인 경우, Mutex는 참조를 유지할 필요가없는 후에도 쓰레기 수집을받을 자격이 없을 수 있습니다.


왜 우리는 두 번 풋을 전화해야합니까?

이 방법이 맵에서 뮤텍스를 강력하게 참조 할 수있을 때까지 처리해야 할 두 가지가 있습니다.

  • 그만큼 약한 참조 수집 된 쓰레기통 (또는 처음에는 결코 거기에 없었습니다)
  • 약점의 내용은 획득 한 후 수집 된 쓰레기입니다.

놓다 한 번만 호출 될 것입니다. 메소드는 즉시 반환됩니다.

(약점은 두 번째 풋에서 재사용 될 수 있지만, 그것이 크게 개선 될 것임을 알지 못합니다.)


물론 코드에서 결함을 찾을 수 있다면 알려 주시면 행복하게 수정하겠습니다. 또한 단위 테스트는 구현이 누출되지 않는지 확인하려고하므로 코드를 자유롭게 수정하고 테스트를 실행할 때 어떤 일이 발생하는지 확인하십시오.

다른 팁

약한 하슈 맵의 값 객체는 일반적인 강력한 참조로 유지됩니다. 따라서 값 객체가 키가 버려지는 것을 막기 때문에 값 객체가 직간접 적으로 자신의 키를 강력하게 언급하지 않도록주의를 기울여야합니다. 값 객체는 약한 해쉬 맵 자체를 통해 간접적으로 키를 참조 할 수 있습니다. 즉, 값 객체는 관련 값 객체가 첫 번째 값 객체의 키를 강력하게 지칭하는 다른 키 객체를 강력하게 지칭 할 수 있습니다. 이것을 다루는 한 가지 방법은 다음과 같이 삽입하기 전에 약한 차지 내에서 값을 스스로 랩핑하는 것입니다. m.put (key, new weecreference (value)), 각 get에 랩핑을 풀는 것입니다.

1- @loop가 있습니다 좋은 대답.

2- 항목이 약한 차고로 래핑한다고 가정하면 두 번째는 put 그 때문에 필요합니다 WeakReference 실행이 줄에 도달하기 전에 수집 될 수 있습니다.

 Mutex mutex = ref.get();

이 경우 :

  • 항목은 아직 존재하지 않을 수 있습니다 map
  • 그것이 존재하는 경우, 그것은 실행하기 전에 수집 될 수 있습니다. Mutex mutex = ref.get();

나는 그렇게 말할 것이다 WeakReferenceHTTP 세션 ID를 참조해야하기 때문에 만 사용됩니다. 항상 100% 확신 할 수는 없을 수는 없습니다. 세션이 종료되므로 맵이 계속 증가 할 수 있습니다.

처음으로 전화 할 때는지도에 키가 포함되어 있지 않기 때문입니다. 두 번째로 맵에 키가 포함되어 있었지만 참조는 더 이상 존재하지 않았기 때문입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top