1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package org.apache.harmony.luni.util; 19 20 import java.lang.ref.SoftReference; 21 import java.nio.CharBuffer; 22 import java.nio.charset.CharsetDecoder; 23 import java.nio.charset.CharsetEncoder; 24 import java.nio.charset.Charsets; 25 26 /** 27 * The class extends the functionality of {@link java.lang.ThreadLocal} with 28 * possibility of discarding the thread local storage content when a heap is 29 * exhausted. 30 */ 31 public class ThreadLocalCache<T> { 32 33 private SoftReference<ThreadLocal<T>> storage = new SoftReference<ThreadLocal<T>>( 34 null); 35 36 private ThreadLocal<T> getThreadLocal() { 37 ThreadLocal<T> tls = storage.get(); 38 if (tls == null) { 39 tls = new ThreadLocal<T>() { 40 public T initialValue() { 41 return ThreadLocalCache.this.initialValue(); 42 } 43 }; 44 storage = new SoftReference<ThreadLocal<T>>(tls); 45 } 46 return tls; 47 } 48 49 /** 50 * Returns the initial value for the cache for the current thread. 51 */ 52 protected T initialValue() { 53 return null; 54 } 55 56 /** 57 * Returns the thread local value of this object. 58 */ 59 public T get() { 60 return getThreadLocal().get(); 61 } 62 63 /** 64 * Sets the value of this variable for the current thread. Might be useful 65 * for expanding the thread local cache. 66 */ 67 public void set(T value) { 68 getThreadLocal().set(value); 69 } 70 71 /** 72 * Discards the cache for all threads. 73 */ 74 public void remove() { 75 storage.clear(); 76 } 77 78 public static ThreadLocalCache<CharsetDecoder> utf8Decoder = new ThreadLocalCache<CharsetDecoder>() { 79 protected CharsetDecoder initialValue() { 80 return Charsets.UTF_8.newDecoder(); 81 } 82 }; 83 84 public static ThreadLocalCache<CharsetEncoder> utf8Encoder = new ThreadLocalCache<CharsetEncoder>() { 85 protected CharsetEncoder initialValue() { 86 return Charsets.UTF_8.newEncoder(); 87 } 88 }; 89 90 public static ThreadLocalCache<java.nio.ByteBuffer> byteBuffer = new ThreadLocalCache<java.nio.ByteBuffer>() { 91 protected java.nio.ByteBuffer initialValue() { 92 return java.nio.ByteBuffer.allocate(72); // >= 93 // Manifest.LINE_LENGTH_LIMIT 94 } 95 }; 96 97 public static ThreadLocalCache<CharBuffer> charBuffer = new ThreadLocalCache<CharBuffer>() { 98 protected CharBuffer initialValue() { 99 return CharBuffer.allocate(72); // no specific requirement 100 } 101 }; 102 103 } 104