我正在编写一个消息传递外观,它接收任意 POJO 并以 JSON 格式通过网络发送它们,工作流程如下:
- 用户调用
MessagingFacade.sendMessage(Object)
- 从池中借用一个ByteBuffer,我们将消息序列化到这个缓冲区
- 通过调用
JsonSerializer.serialize(Object, ByteBuffer)
将 POJO 转换为 JSON - 通过网络发送编码消息
Transport.send(ByteBuffer)
, 保留对 promise 的引用,该 promise 将在消息发送后得到通知 - 将回调附加到 promise 中,一旦 ByteBuffer 被写入线路就将其返回到池中
- 返回自
MessagingFacade.sendMessage(Object)
调用
如果我们可以调用 clear()
,这是一个用于池化 ByteBuffer 的相对简单的用例。当对象返回到池中时重置状态。
我没有编写自己的对象池,而是尝试利用 Apache 中已经提供的对象池 commons-pool
.但是,GenericObjectPool
似乎有一个相当大的警告。和 SoftReferenceObjectPool
...
借用/归还对象时,这两个池都在使用hashCode()
和/或 equals()
识别关联的 PooledObject<ByteBuffer>
.这对 ByteBuffer
有非常实际的影响。 ,给定 equals()
和 hashCode()
实现涉及评估底层的内容 byte
数组:
- 清理对象 - 当
ByteBuffer
返回到池中,它的状态为“已清理”。这只涉及调用ByteBuffer.clear()
.这不会将数组中的所有字节清零,这意味着equals()
和hashCode()
返回ByteBuffer
时给出不同的结果,与借用时的对比。 - 评估速度 - 考虑到我正在汇集
ByteBuffer
的实例容量为我的最大消息大小 (1MB),同时评估hashCode()
和equals()
必须线性遍历这个非常大的数组
Apache commons-pool 实现似乎不适合任何 (a) 类具有昂贵的 equals()
的用例。和 hashCode()
实现或 (b) hashCode()
清洗后不会产生稳定的结果。
制作GenericObjectPool
的唯一可行选择或 SoftReferenceObjectPool
这个用例的工作似乎是包装 ByteBuffer
在另一个使用身份相等/哈希码逻辑的类中。
这是可行的,但考虑到这个用例的普通程度,感觉有点麻烦。这种方法有更好的替代方法吗?
最后一点;由于 equals()
的不稳定和 hashCode()
实际上会从 GenericObjectPool
中得到异常,因为池认为您正在尝试返回一个从未从池中借用的对象:
java.lang.IllegalStateException: Returned object not currently part of this pool
at org.apache.commons.pool2.impl.GenericObjectPool.returnObject(GenericObjectPool.java:537)
...
最佳答案
您所指的限制已在 JIRA 问题 POOL-283 和 POOL-284 中确定,这些问题已在 Commons Pool 2.4.1 版中得到解决。尝试升级到版本 2.4.1。
关于java - 有效地池化 ByteBuffer 的实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29537870/