Home | History | Annotate | Download | only in util
      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