com.ibm.icu.impl.locale.LocaleObjectCache Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of icu4j Show documentation
Show all versions of icu4j Show documentation
International Component for Unicode for Java (ICU4J) is a mature, widely used Java library
providing Unicode and Globalization support
/*
*******************************************************************************
* Copyright (C) 2009-2010, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
package com.ibm.icu.impl.locale;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.concurrent.ConcurrentHashMap;
public abstract class LocaleObjectCache {
private ConcurrentHashMap> _map;
private ReferenceQueue _queue = new ReferenceQueue();
public LocaleObjectCache() {
this(16, 0.75f, 16);
}
public LocaleObjectCache(int initialCapacity, float loadFactor, int concurrencyLevel) {
_map = new ConcurrentHashMap>(initialCapacity, loadFactor, concurrencyLevel);
}
public V get(K key) {
V value = null;
cleanStaleEntries();
CacheEntry entry = _map.get(key);
if (entry != null) {
value = entry.get();
}
if (value == null) {
key = normalizeKey(key);
V newVal = createObject(key);
if (key == null || newVal == null) {
// subclass must return non-null key/value object
return null;
}
CacheEntry newEntry = new CacheEntry(key, newVal, _queue);
while (value == null) {
cleanStaleEntries();
entry = _map.putIfAbsent(key, newEntry);
if (entry == null) {
value = newVal;
break;
} else {
value = entry.get();
}
}
}
return value;
}
@SuppressWarnings("unchecked")
private void cleanStaleEntries() {
CacheEntry entry;
while ((entry = (CacheEntry)_queue.poll()) != null) {
_map.remove(entry.getKey());
}
}
protected abstract V createObject(K key);
protected K normalizeKey(K key) {
return key;
}
private static class CacheEntry extends SoftReference {
private K _key;
CacheEntry(K key, V value, ReferenceQueue queue) {
super(value, queue);
_key = key;
}
K getKey() {
return _key;
}
}
}