decoder解码优化

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 条评论。

发表评论


注意 - 你可以用以下 HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>


Warning: Use of undefined constant XML - assumed 'XML' (this will throw an Error in a future version of PHP) in /opt/wordpress/wp-content/plugins/wp-syntaxhighlighter/wp-syntaxhighlighter.php on line 1048