decoder中需要使用byte[]接收数据并转为protobuf对象。
本来考虑的是使用netty自带的缓存功能或直接在每个decoder中分配一个byte[]。这时想起来了fastjson的作者提过使用的线程绑定的byte[]功能。
查找到源代码,摘出来用。也感谢fastjson的作者开源代码。
package cn.joylab.game.util;
import java.lang.ref.SoftReference;
/**
* 提供线程绑定数组缓存功能。
*
* 可以避免频繁创建byte数组,最大长度限制为128k,超过128k的数据不进行缓存。
*
* 用例1:decoder.
*
* @author ZhuKunqian
*
*/
public class ThreadLocalCache {
private final static int BYTE_CACHE_INIT_SIZE = 1024;
private final static int BYTE_CACHE_MAX_SIZE = 1024 * 128;
private static final ThreadLocal<SoftReference<byte[]>> byteBufLocal = new ThreadLocal<SoftReference<byte[]>>();
public static void clearCache() {
byteBufLocal.set(null);
}
public static byte[] getBytes(int length) {
SoftReference<byte[]> ref = byteBufLocal.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 int getAllocateLength(int init, int max, int length) {
int value = init;
while (true) {
if (value >= length) {
return value;
}
value *= 2;
if (value > max) {
break;
}
}
return length;
}
private static byte[] allocateBytes(int length) {
int allocateLength = getAllocateLength(BYTE_CACHE_INIT_SIZE,
BYTE_CACHE_MAX_SIZE, length);
if (allocateLength <= BYTE_CACHE_MAX_SIZE) {
byte[] bytes = new byte[allocateLength];
byteBufLocal.set(new SoftReference<byte[]>(bytes));
return bytes;
}
return new byte[length];
}
}
0 条评论。