在物联网合并帧的时候,有时候会有特定长度的二进制数据需要合并,这种合并很需要byte[]数组,然后因为物联网硬件设备特别多,非常容易造成OOM的情况。针对这种情况,我想通过对象池模式,来解决这个问题。
把所需的byte长度作为key,4就取byte[4]长度数组,5就取byte[5]长度数据!String类型考虑它的常量池特性!
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
public class ByteArrayFactory {
public static ConcurrentHashMap<String, ConcurrentLinkedQueue<byte[]>> hashLinkMap = new ConcurrentHashMap<>();
/**
* 根据长度,获取对应的byte[]数组
* @param len
* @return
*/
public static byte[] getBytes(String len) {
ConcurrentLinkedQueue<byte[]> queue = null;
if(hashLinkMap.get(len) == null) {
queue = new ConcurrentLinkedQueue();
hashLinkMap.put(len,queue);
}
queue = hashLinkMap.get(len);
byte[] buff = queue.poll();
if(buff == null) {
buff = new byte[Integer.parseInt(len)];
}
return buff;
}
/**
* 回收对应的byte[]数组
* @param array
*/
public static void recycle(byte[] array) {
String len = array.length + "";
for(int i =0; i < array.length; i++) {
array[i] = 0x20;
}
ConcurrentLinkedQueue<byte[]> queue = hashLinkMap.get(len);
queue.offer(array);
}
}
使用场景:
/**
* 合并byte[] 数组
* @param byteArray byte数组
* @return 返回合并后的byte[]数组
*/
public static byte[] combinationContent(byte[]... byteArray)
{
int len = 0;
for(byte[] buff:byteArray)
{
len += buff.length;
}
ByteBuffer byteBuffer = ByteBuffer.wrap(ByteArrayFactory.getBytes(len + "")); //ByteBuffer.allocate(len);
for(byte[] buff:byteArray)
{
byteBuffer.put(buff);
}
byte[] buff = byteBuffer.array();
return buff;
}
//合并二进制数据之后,它就可以回收了。
public static byte[] diandao(int value) {
byte[] content = DigitalConversion.integerConvertFourNumber(value);
byte[] childFrame = ByteCombination.combinationContent(diandaoHead,content,diandaoTail);
ByteArrayFactory.recycle(content);
return LargeScreenFrame.gatherPacket(childFrame);
}
有物联网技术讨论的,私信我交流学习下!