한가 할 때 자바 의 부 드 러 운 인용 으로 짝 퉁 캐 시 를 썼 다.
자, 잡담 은 그만 하고 본론 으로 들 어가 자. 자바 의 인용 은 StrongReference, SoftReference, WeakReference, PhantomReference 로 나 뉜 다.이 몇 가지 인용 은 서로 다른 사용 장면 이 있 는데 평소에 우리 가 가장 자주 사용 하 는 것 은 바로 StrongReference 이다. 즉, 이와 같은 인용 이다.
Object obj = new Object();
이러한 인용 은 이른바 강 한 인용 이다. 이 대상 이 가리 키 는 것 을 인용 하지 않 고 살 아 있 는 스 레 드 가 접근 할 수 없다 면 (쓰레기 외 딴 섬 에 대해 서 는) 그 는 회수 되 고 이 대상 이 강 한 인용 으로 가리 키 며 메모리 가 다 소모 되면 OOM 쓰레기 수집 기 를 던 져 도 이 대상 을 회수 하지 않 을 것 이다.
한편, SoftReference 의 경우 GC 에 의 해 회수 되 는 조건 이 그리 엄격 하지 않 습 니 다. 만약 에 한 대상 이 현재 가장 강 한 인용 이 소프트 인용 이 고 JVM 의 메모리 가 충분 하 다 면 쓰레기 회수 기 는 회수 되 지 않 을 것 입 니 다.메모리 가 부족 한 경우 에 만 GC 는 소프트 참조 가 가리 키 는 대상 을 회수 할 수 있 습 니 다. 이 특징 을 통 해 소프트 인용 은 고속 캐 시 를 만 들 고 LRU 정책 에 맞 추 는 것 이 좋 습 니 다.오늘 은 내 가 하나 써 서 놀 게.
:
package com.blackbeans.example;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.HashMap;
/**
*
* @author blackbeans
* @param <K>
* @param <T>
*/
public class ReferenceCache<K,T> {
private HashMap<K, InnerReference<K,T>> cachedReference = new HashMap<K, InnerReference<K,T>>(1024);
private final ReferenceQueue<T> referenceQueue ;
private final ObjectNotFoundHandler<K,T> existsHandler;
/**
*
* @author blackbeans
*
* @param <K>
* @param <T>
*/
private static class DefaultObjectNotFoundHandler<K,T> implements ObjectNotFoundHandler<K,T>
{
@Override
public T queryAndCached(K key) {
// TODO Auto-generated method stub
return null;
}
}
/**
*
* @author blackbeans
*
* @param <K>
* @param <T>
*/
public static interface ObjectNotFoundHandler<K,T>
{
public T queryAndCached(K key);
}
private static class InnerReference<K,T> extends SoftReference<T>{
private final K key ;
public InnerReference(K key,T reference,ReferenceQueue<T> queue) {
super(reference,queue);
this.key = key;
}
public K getKey()
{
return this.key;
}
}
public ReferenceCache(ObjectNotFoundHandler<K,T> handler)
{
this.referenceQueue = new ReferenceQueue<T>();
this.existsHandler = handler == null ? new DefaultObjectNotFoundHandler<K,T>() : handler;
}
public ReferenceCache()
{
this(null);
}
public void cachedReference(K key,T reference)
{
/**
* reference
*/
cleanReference(key);
if(!this.cachedReference.containsKey(key))
{
this.cachedReference.put(key, new InnerReference<K,T>(key,reference, this.referenceQueue));
}
}
public T getReference(K key) {
T obj = null;
if(this.cachedReference.containsKey(key)){
obj = this.cachedReference.get(key).get();
}
if(null == obj)
{
/**
* ,
*/
obj = this.existsHandler.queryAndCached(key);
this.cachedReference(key, obj);
return obj;
}
return obj;
}
@SuppressWarnings("unchecked")
private void cleanReference(K key) {
// key
if (this.cachedReference.containsKey(key)
&& this.cachedReference.get(key).get() == null)
this.cachedReference.remove(key);
T obj = null;
// Key Key
Reference<? extends T> reference = null;
while((reference = this.referenceQueue.poll()) != null)
{
obj = reference.get();
if(obj == null)
{
this.cachedReference.remove(((InnerReference<K, T>)reference).getKey());
}
}
}
public void clearALLObject()
{
this.cachedReference.clear();
System.gc();
}
}
전체 구현 에서 대상 의 인용 을 내 가 정의 한 key - > 소프트 인용 map 에 넣 은 다음 cache 에서 대상 을 가 져 올 때마다 먼저 key 를 통 해 map 를 조회 하여 대상 의 소프트 인용 을 얻 고 존재 하면 소프트 인용 을 통 해 대상 을 가 져 오 려 고 시도 합 니 다. 존재 하지 않 으 면 소프트 인용 이 가리 키 는 대상 이 회수 되면 우 리 는 내 장 된 handler 를 호출 합 니 다.대상 을 다시 만 들 고 cache 대상 의 소프트 참조 입 니 다.
제 실현 에서 저 는 사용자 에 게 대상 이 회수 되 었 을 때의 처리 handler 를 제공 하여 사용자 가 이 handler 를 통 해 대상 을 재 구성 하도록 지도 하려 고 했 습 니 다. 캐 시 대상 은 유연성 이 매우 큽 니 다.
부 드 럽 게 인 용 된 캐 시가 LRU 정책 으로 완벽 해 지면 LRU 정책 을 사용자 정의 할 수 있 는 Processor 를 제공 하 는 것 이 부족 하 다.사실 간단 합 니 다. HashMap 을 링크 드 HashMap 으로 바 꾸 어 removeEldest 방법 을 실현 하고 방법 에서 사용자 정의 LRU 프로 세 서 를 호출 하면 됩 니 다.
비용 을 줄 이기 위해 서, 나 는 캐 치 할 때마다 이미 효력 을 잃 은 소프트 인용 을 정리 했다.왜 Reference Queue 가 있 냐 고 물 어보 실 수도 있어 요.사실은 이 렇 습 니 다. 소프트 인용 이 인용 한 대상 이 회수 되 었 다 고 생각 한 후에 대상 의 소프트 인용 대상 은 회수 되 었 습 니 다. 그러나 다른 대상 인 SoftReference 를 도 입 했 습 니 다. 하 나 를 가 져 가면 하나 더 남 겨 야 하 는 지 생각 하지 않 습 니 다. 소프트 인용 대상 이 회수 되면 이 소프트 인용 자체 가 이 quue 에 추가 되 어 회 수 를 기다 리 고 있 습 니 다.이 quue 를 편리 하 게 해서 소프트 인용 을 가 져 와 map 에서 만 료 된 소프트 인용 을 가 져 옵 니 다.
이로써 할 말 도 다 했 고 하지 말 아야 할 말 도 했 습 니 다. 결말 이 매우 갑 작 스 러 우 니 양해 해 주 십시오!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.