SimpleDateFormat结合对象池化工具commons-pool
2017-12-10 13:09
477 查看
关于对象池的概念这里不做过多解释,除了用来缓存数据库连接java.sql.Connection这种重量级对象也适用于其他场景。
以SimpleDateFormat 为例,这是 Java 中非常常用的一个类,用于解析和格式化日期字符串。
但是 SimpleDateFormat 在多线程环境中并不是线程安全的。详见这位仁兄的 SimpleDateFormat 的线程安全问题与 ThreadLocal
实现线程安全的一种思路是用ThreadLocal进行安全变量的副本。
但是维持变量副本的资源也是需要消耗资源的。尽管ThreadLocal提供了remove方法以便在请求结束后释放副本,但若在请求结束的时候崩溃副本没有得到释放,将会给内存造成极大的压力。为了应对这种情况我们可以采用jdbc连接池的思想,把对象放入对象池工具里面,用”pool”来约束对象的创建与销毁。
首先引入Apache commons-pool依赖
接口的声明
实现类
测试
核心实现都在 org.apache.commons.pool.impl.GenericObjectPool里面
这里只展示几个关键参数
以SimpleDateFormat 为例,这是 Java 中非常常用的一个类,用于解析和格式化日期字符串。
但是 SimpleDateFormat 在多线程环境中并不是线程安全的。详见这位仁兄的 SimpleDateFormat 的线程安全问题与 ThreadLocal
实现线程安全的一种思路是用ThreadLocal进行安全变量的副本。
static ThreadLocal<SimpleDateFormat> format1 = new ThreadLocal<SimpleDateFormat>() { @Override protected SimpleDateFormat initialValue() { return new SimpleDateFormat("yyyy-MM-dd"); } }; public String formatDate(Date date) { return format1.get().format(date); }
但是维持变量副本的资源也是需要消耗资源的。尽管ThreadLocal提供了remove方法以便在请求结束后释放副本,但若在请求结束的时候崩溃副本没有得到释放,将会给内存造成极大的压力。为了应对这种情况我们可以采用jdbc连接池的思想,把对象放入对象池工具里面,用”pool”来约束对象的创建与销毁。
首先引入Apache commons-pool依赖
<dependency> <groupId>commons-pool</groupId> <artifactId>commons-pool</artifactId> <version>1.6</version> </dependency>
接口的声明
//接口 import java.util.Date; public interface FormattingService { String format(Date date); void setPattern(String pattern); }
实现类
import java.text.SimpleDateFormat; import java.util.Date; import java.util.concurrent.atomic.AtomicInteger; import org.apache.commons.pool.BasePoolableObjectFactory; import org.apache.commons.pool.PoolableObjectFactory; import org.apache.commons.pool.impl.GenericObjectPool; public class PooledFormattingService implements FormattingService { // 对象池的实现 GenericObjectPool<SimpleDateFormat> dateFormatsPool; private static AtomicInteger count = new AtomicInteger(0); String pattern; public PooledFormattingService() { // 对象池工厂 PoolableObjectFactory factory = new Bas a828 ePoolableObjectFactory() { @Override public Object makeObject() throws Exception { System.out.println("创建新对象"+(count.incrementAndGet())); return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); } }; dateFormatsPool = new GenericObjectPool(factory); // 这里设置创建新对象的最大数目 dateFormatsPool.setMaxActive(10); } public String format(Date date) { try { SimpleDateFormat dateFormat = this.dateFormatsPool.borrowObject(); try { return dateFormat.format(date); } finally { this.dateFormatsPool.returnObject(dateFormat); } } catch (Exception e) { throw new RuntimeException(e); } } public void setPattern(final String pattern) { PoolableObjectFactory factory = new BasePoolableObjectFactory() { @Override public Object makeObject() throws Exception { return new SimpleDateFormat(pattern); } }; this.dateFormatsPool = new GenericObjectPool(factory); } }
测试
import java.util.Date; public class Mytest { public static void main(String[] args) { PooledFormattingService pooledFormattingService = new PooledFormattingService(); //创建20个线程去调用SimpleDateFormat //由于对象池为10,SimpleDateFormat最多创建10个 for (int i = 0; i < 20; i++) { new Thread(() -> { pooledFormattingService.format(new Date()); }).start(); } } }
核心实现都在 org.apache.commons.pool.impl.GenericObjectPool里面
这里只展示几个关键参数
maxActive: 链接池中最大连接数,默认为8. maxIdle: 链接池中最大空闲的连接数,默认为8. minIdle: 连接池中最少空闲的连接数,默认为0. maxWait: 当连接池资源耗尽时,调用者最大阻塞的时间,超时将抛异常。默认永不超时. minEvictableIdleTimeMillis: 连接空闲的最小时间,达到此值后空闲连接将可能会被移除。 softMinEvictableIdleTimeMillis: 连接空闲的最小时间,达到此值后空闲链接将会被移除 numTestsPerEvictionRun: 对于“空闲链接”检测线程而言,每次检测的链接资源的个数。默认为3.
相关文章推荐
- Apache的对象池化工具commons-pool
- Apache的对象池化工具commons-pool
- 使用Jakarta Commons Pool处理对象池化(zz)
- commons-lang(time应用),解决simpleDateFormat性能和安全问题
- 对象池化技术 org.apache.commons.pool
- 对象池化技术 org.apache.commons.pool
- 对象池化技术 org.apache.commons.pool
- 使用Jakarta Commons Pool处理对象池化(二)(zt)
- 对象池化技术 org.apache.commons.pool
- 使用Jakarta Commons Pool处理对象池化(一)(zt)
- 对象池化技术 org.apache.commons.pool
- 对象池化技术 org.apache.commons.pool
- SimpleDateFormat 非线程安全
- java.text.SimpleDateFormat使用介绍
- SimpleDateFormat使用详解
- SimpleDateFormat
- SimpleDateFormat使用详解
- SimpleDateFormat小记
- 深入理解Java:SimpleDateFormat安全的时间格式化
- SimpleDateFormat的线程安全问题与解决方案(ThreadLocal)