LinkedHashMap에서 유사한 기능을 사용하여 ConcurRenthashMap을 구현하는 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/1815646

문제

나는 사용했다 LinkedHashMap ~와 함께 accessOrder 데이터의 LRU 캐시로 언제든지 최대 500 개의 항목을 허용하는 것과 함께 True. 그러나 확장 성 문제로 인해 일부 스레드 안전 대안으로 이동하고 싶습니다. ConcurrentHashMap 그 점에서 좋은 것 같지만의 특징이 부족합니다. accessOrder 그리고 removeEldestEntry(Map.Entry e) 발견되었습니다 LinkedHashMap. 누구든지 링크를 가리키거나 구현을 용이하게 할 수 있도록 도와 줄 수 있습니다.

도움이 되었습니까?

해결책

나는 최근에 비슷한 일을했다 ConcurrentHashMap<String,CacheEntry>, 캐시 엔트리가 실제 항목을 감싸고 캐시 퇴거 통계를 추가하는 경우 : 만료 시간, 삽입 시간 (FIFO/LIFO 퇴거의 경우), 마지막 사용 시간 (LRU/MRU 퇴거의 경우), 적중 수 (LFU/MFU 퇴거의 경우) 등 실제 퇴거는 동기화되어 an을 생성합니다 ArrayList<CacheEntry> 퇴거 전략에 적합한 비교기를 사용하여 collections.sort ()를 수행합니다. 이것은 비싸기 때문에 각 퇴거는 캐시 엔트리의 바닥 5%를 벗어납니다. 그래도 성능 튜닝이 도움이 될 것이라고 확신합니다.

귀하의 경우 FIFO를하고 있기 때문에 별도의 동시에 린드 큐. ConcurrEthashMap에 객체를 추가하면 해당 객체의 ConcurrentLinkedqueue.add ()를 수행하십시오. 항목을 퇴거시키고 싶을 때 동의어 링크 Queue.poll ()을 수행하여 가장 오래된 객체를 제거한 다음 동의어에서도 제거하십시오.

업데이트 :이 분야의 기타 가능성에는 Java 컬렉션이 포함됩니다. 동기화 래퍼 그리고 Java 1.6 ConcurrentsKipListMap.

다른 팁

Ehcache와 같은 많은 캐싱 솔루션 중 하나를 사용해 보셨습니까? readWritelock과 함께 LinkedHashMap을 사용해 볼 수 있습니다. 이것은 당신에게 동시 읽기 액세스를 줄 것입니다.

이것은 이제 오래된 것처럼 보일지 모르지만 적어도 내 역사 추적을 위해서는 내 솔루션을 여기에 추가 할 것입니다. 약점의 k-> 서브 클래스, ConcurrentLinkedqueue 및 값 객체의 사막화를 정의하는 인터페이스를 맵핑하는 ConsurenthashMap을 결합했습니다. LRU 캐싱을 올바르게 실행하려는 K를 기반으로합니다. 대기열은 강한 심판을 보유하고 있으며 GC는 적절한 경우 메모리에서 값을 퇴거시킵니다. Atomicinteger와 관련된 대기열 크기를 추적합니다. 대기열을 검사하여 언제 퇴거 시야를 결정할 수 없기 때문입니다. 캐시는 큐 관리뿐만 아니라 대기열에 퇴거/추가를 처리합니다. GC가 메모리에서 값을 퇴거 시키면 사막화 인터페이스의 구현은 값을 되 찾는 것을 처리합니다. 또한 스풀링 된 내용을 다시 읽기 위해 스풀링/디스크에 대한 스풀링과 관련된 또 다른 구현이 있었지만 스풀링/읽기를 동기화하기 위해 IHAD가 여기에 게시 한 솔루션보다 훨씬 느 렸습니다.

"스레드-안전"대안으로 확장 성 문제를 해결하고자하는 것을 언급합니다. 여기서 "스레드 안전"은 구조가 관대 한 동시 접근 시도의 시도는 외부 동기화없이 동시에 사용하여 부패를 겪지 않을 것입니다. 그러나 이러한 공차가 반드시 "확장 성"을 향상시키는 데 도움이되지는 않습니다. 가장 간단한 경우-일반적으로 잘못 안내하지만 접근 방식은 내부적으로 구조를 동기화하고 여전히 비 원자를 남기려고 노력할 것입니다. 체크 아 먹기 안전하지 않은 운영.

LRU 캐시는 전체 구조에 대한 인식이 적어도 필요합니다. 그들은 퇴거시기를 결정하기 위해 회원의 수 또는 회원의 규모와 같은 것이 필요하며, 퇴거를 동시에 읽고, 추가 또는 제거하려는 동시에 퇴거를 조정할 수 있어야합니다. "주요"구조에 대한 동시에 접근하는 데 필요한 동기화를 줄이려고 노력하고 퇴거 메커니즘에 대한 전투와 퇴거 정책이 보증이 덜 정확 해집니다.

현재 인정 된 답변은 "항목을 퇴거시키고 싶을 때"를 언급합니다. 그 안에 문지름이 있습니다. 항목을 퇴거하고 싶은시기를 어떻게 알 수 있습니까? 이 결정을 내리려면 어떤 다른 작업을 일시 중지해야합니까?

지도를 a Collections.synchronizedMap(). 그렇다면 추가 방법을 호출 해야하는 경우 synchronize 이 전화에서 돌아온지도에서 원래지도에서 원본 메소드를 호출합니다 (예를 들어 Javadocs를 참조하십시오). 키 등을 반복 할 때도 마찬가지입니다.

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