2 *******************************************************************************
3 * Copyright (C) 2009-2010, International Business Machines Corporation and *
4 * others. All Rights Reserved. *
5 *******************************************************************************
7 package com.ibm.icu.impl.locale;
9 import java.lang.ref.ReferenceQueue;
10 import java.lang.ref.SoftReference;
11 import java.util.concurrent.ConcurrentHashMap;
13 public abstract class LocaleObjectCache<K, V> {
14 private ConcurrentHashMap<K, CacheEntry<K, V>> _map;
15 private ReferenceQueue<V> _queue = new ReferenceQueue<V>();
17 public LocaleObjectCache() {
21 public LocaleObjectCache(int initialCapacity, float loadFactor, int concurrencyLevel) {
22 _map = new ConcurrentHashMap<K, CacheEntry<K, V>>(initialCapacity, loadFactor, concurrencyLevel);
29 CacheEntry<K, V> entry = _map.get(key);
34 key = normalizeKey(key);
35 V newVal = createObject(key);
36 if (key == null || newVal == null) {
37 // subclass must return non-null key/value object
41 CacheEntry<K, V> newEntry = new CacheEntry<K, V>(key, newVal, _queue);
43 while (value == null) {
45 entry = _map.putIfAbsent(key, newEntry);
57 @SuppressWarnings("unchecked")
58 private void cleanStaleEntries() {
59 CacheEntry<K, V> entry;
60 while ((entry = (CacheEntry<K, V>)_queue.poll()) != null) {
61 _map.remove(entry.getKey());
65 protected abstract V createObject(K key);
67 protected K normalizeKey(K key) {
71 private static class CacheEntry<K, V> extends SoftReference<V> {
74 CacheEntry(K key, V value, ReferenceQueue<V> queue) {