当对象的创建比较昂贵的时候,且生命周期通常较短的时候,将对象池化是一个比较不错的选择。对象池给对象提供了一个缓存。
可能业务代码中用到的地方并不是很多,对象池的一个比较不错的应用点是RPC框架中的序列化部分,很多序列化框架自带了对象池,比如KryoPool。
改造现有代码使用对象池并不复杂,无非就是选择一个对象池框架,然后修改对象的获取和释放。
比较常见的对象池库肯定是apache-common-pool了,它提供了数种不同类型和实现的池,大部分时候直接用它就行了。
一个简单的例子
public class ReaderUtil { private ObjectPool<StringBuffer> pool; public ReaderUtil(ObjectPool<StringBuffer> pool) { this.pool = pool; } /** * Dumps the contents of the {@link Reader} to a String, closing the {@link Reader} when done. */ public String readToString(Reader in) throws IOException { StringBuffer buf = null; try { buf = pool.borrowObject(); for (int c = in.read(); c != -1; c = in.read()) { buf.append((char) c); } return buf.toString(); } catch (IOException e) { throw e; } catch (Exception e) { throw new RuntimeException("Unable to borrow buffer from pool" + e.toString()); } finally { try { in.close(); } catch (Exception e) { // ignored } try { if (null != buf) { pool.returnObject(buf); } } catch (Exception e) { // ignored } } } }
可以看出使用对象池的关键就是将对象重置这个行为交给对象池处理。池的使用可能有多线程竞争问题,不过大部分库都能够处理这个问题。
当然一般考虑到对象池了自然是有性能上的需求,这里有一些小众的对象池
https://github.com/DanielYWoo/fast-object-pool
https://github.com/chrisvest/stormpot/
https://github.com/vibur/vibur-object-pool
还有一些是其他项目中的对象池,比如使用数据库连接池中的对象池(https://github.com/brettwooldridge/HikariCP)
https://commons.apache.org/proper/commons-pool/
https://commons.apache.org/proper/commons-pool/apidocs/org/apache/commons/pool2/impl/GenericObjectPool.html