Leachashmap.put (..)에 대한 이중 호출의 추론은 무엇입니까?
-
05-07-2019 - |
문제
이것 블로그 게시물 문자열 ID 관용구 당 뮤텍스를 구현하는 방법을 보여줍니다. 사용 된 문자열 ID는 httpsession ID를 나타내는 것입니다.
- 왜 우리는 Mutex 인스턴스 주변에서 약한 회의를 포장해야합니까? String-> mutex에서 맵을 만드는 것이 낫지 않습니까?
왜 우리는 두 번 풋을 전화해야합니까?
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();
나는 그렇게 말할 것이다 WeakReference
HTTP 세션 ID를 참조해야하기 때문에 만 사용됩니다. 항상 100% 확신 할 수는 없을 수는 없습니다. 세션이 종료되므로 맵이 계속 증가 할 수 있습니다.
처음으로 전화 할 때는지도에 키가 포함되어 있지 않기 때문입니다. 두 번째로 맵에 키가 포함되어 있었지만 참조는 더 이상 존재하지 않았기 때문입니다.