package com.alibaba.fastjson.util; import java.lang.ref.SoftReference; import java.nio.charset.CharsetDecoder; public class ThreadLocalCache { public final static int CHARS_CACH_INIT_SIZE = 1024; // 1k; public final static int CHARS_CACH_MAX_SIZE = 1024 * 128; // 1k; private final static ThreadLocal<SoftReference<char[]>> charsBufLocal = new ThreadLocal<SoftReference<char[]>>(); private final static ThreadLocal<CharsetDecoder> decoderLocal = new ThreadLocal<CharsetDecoder>(); public static CharsetDecoder getUTF8Decoder() { CharsetDecoder decoder = decoderLocal.get(); if (decoder == null) { decoder = new UTF8Decoder(); decoderLocal.set(decoder); } return decoder; } public static void clearChars() { charsBufLocal.set(null); } public static char[] getChars(int length) { SoftReference<char[]> ref = charsBufLocal.get(); if (ref == null) { return allocate(length); } char[] chars = ref.get(); if (chars == null) { return allocate(length); } if (chars.length < length) { chars = allocate(length); } return chars; } private static char[] allocate(int length) { int allocateLength = getAllocateLength(CHARS_CACH_INIT_SIZE, CHARS_CACH_MAX_SIZE, length); if (allocateLength <= CHARS_CACH_MAX_SIZE) { char[] chars = new char[allocateLength]; charsBufLocal.set(new SoftReference<char[]>(chars)); return chars; } return new char[length]; } private static int getAllocateLength(int init, int max, int length) { int value = init; for (;;) { if (value >= length) { return value; } value *= 2; if (value > max) { break; } } return length; } // ///////// public final static int BYTES_CACH_INIT_SIZE = 1024; // 1k; public final static int BYTeS_CACH_MAX_SIZE = 1024 * 128; // 1k; private final static ThreadLocal<SoftReference<byte[]>> bytesBufLocal = new ThreadLocal<SoftReference<byte[]>>(); public static void clearBytes() { bytesBufLocal.set(null); } public static byte[] getBytes(int length) { SoftReference<byte[]> ref = bytesBufLocal.get(); if (ref == null) { return allocateBytes(length); } byte[] bytes = ref.get(); if (bytes == null) { return allocateBytes(length); } if (bytes.length < length) { bytes = allocateBytes(length); } return bytes; } private static byte[] allocateBytes(int length) { int allocateLength = getAllocateLength(CHARS_CACH_INIT_SIZE, CHARS_CACH_MAX_SIZE, length); if (allocateLength <= CHARS_CACH_MAX_SIZE) { byte[] chars = new byte[allocateLength]; bytesBufLocal.set(new SoftReference<byte[]>(chars)); return chars; } return new byte[length]; } }