2 *******************************************************************************
\r
3 * Copyright (C) 2009, International Business Machines Corporation and *
\r
4 * others. All Rights Reserved. *
\r
5 *******************************************************************************
\r
7 package com.ibm.icu.impl.locale;
\r
9 import java.lang.ref.Reference;
\r
10 import java.lang.ref.ReferenceQueue;
\r
11 import java.lang.ref.WeakReference;
\r
12 import java.util.concurrent.ConcurrentHashMap;
\r
14 public class LocaleObjectCache<K, V> {
\r
16 private ConcurrentHashMap<K, WeakValueRef<V>> _map = new ConcurrentHashMap<K, WeakValueRef<V>>();
\r
17 private ReferenceQueue<V> _rq = new ReferenceQueue<V>();
\r
19 public LocaleObjectCache() {
\r
22 public V get(Object key) {
\r
23 expungeStaleEntries();
\r
24 WeakValueRef<V> ref = _map.get(key);
\r
32 * Unlike Map#put, this method returns non-null value actually
\r
33 * in the cache, even no values for the key was not available
\r
36 public V put(K key, V value) {
\r
37 expungeStaleEntries();
\r
38 WeakValueRef<V> ref = _map.get(key);
\r
40 // Make sure if another thread put the new value
\r
41 V valInCache = ref.get();
\r
42 if (valInCache != null) {
\r
46 // We do not synchronize the internal map here.
\r
47 // In the worst case, another thread may put the new
\r
48 // value with the same contents, but it should not cause
\r
49 // any serious problem.
\r
50 _map.put(key, new WeakValueRef<V>(key, value, _rq));
\r
54 private void expungeStaleEntries() {
\r
55 Reference<? extends V> val;
\r
56 while ((val = _rq.poll()) != null) {
\r
57 Object key = ((WeakValueRef<?>)val).getKey();
\r
62 private static class WeakValueRef<V> extends WeakReference<V> {
\r
63 private Object _key;
\r
65 public WeakValueRef(Object key, V value, ReferenceQueue<V> rq) {
\r
74 public Object getKey() {
\r