一个简单的Java对象池实现——可用来解决SimpleDateFormat的线程安全问题
来源:互联网 发布:知乎 美国 编辑:程序博客网 时间:2024/06/16 03:35
被SimpleDateFormat的线程安全问题困扰过的人应该不止我一个吧。为了解决这个类的线程安全问题,通常我们会有以下两种做法:
- 每次都new 一个SimpleDateFormat对象,但频繁的创建与销毁对象带来的性能问题……哈哈,我就不在这里过多的BB了。
- 使用ThreadLocal技术,这恐怕是最常用的一种解决方案,我想几乎每个有经验的Java程序员都使用过它,在此我也不多说啦,如果真有不知到的,且看下面这篇博文:
SimpleDateFormat的线程安全问题与解决方案
然而,最近在调试过程中意外进入了 XStream这个类库, XStream是一个可以将javaBean与XML双向转换的java类库,本文内容基于xstream-1.4.9版本。所需maven依赖如下:
<dependency> <groupId>com.thoughtworks.xstream</groupId> <artifactId>xstream</artifactId> <version>1.4.9</version></dependency>
不过,本文不是讲解这个类库是如何使用的,而是想说,我在这个类库中发现了一种新颖的可以避免SimpleDateFormat线程安全问题的实现:也即采用对象池,让不同的线程可以使用对象池中不同的SimpleDateFormat对象,并且保证在同一时刻池中的任一对象只能被一条线程使用,从而避免线程安全。
当然XStream中的对象池的实现及其简单,只有简单的借出对象和归还对象,所以完善程度远远无法和apache common pool这种通用且成熟的对象池实现相比(进一个类,数行代码)。不过对于帮助我没理解对象池如何实现到是大有用处。由于实现简单,我就不多解释了,直接贴代码吧。
对象池的简单java实现如下(出自XStream库)
public class Pool { public interface Factory { public Object newInstance(); } private final int initialPoolSize; private final int maxPoolSize; private final Factory factory; private transient Object[] pool; private transient int nextAvailable; private transient Object mutex = new Object(); public Pool(int initialPoolSize, int maxPoolSize, Factory factory) { this.initialPoolSize = initialPoolSize; this.maxPoolSize = maxPoolSize; this.factory = factory; } public Object fetchFromPool() { Object result; synchronized (mutex) { if (pool == null) { pool = new Object[maxPoolSize]; for (nextAvailable = initialPoolSize; nextAvailable > 0; ) { putInPool(factory.newInstance()); } } while (nextAvailable == maxPoolSize) { try { mutex.wait(); } catch (InterruptedException e) { throw new RuntimeException("Interrupted whilst waiting " + "for a free item in the pool : " + e.getMessage()); } } result = pool[nextAvailable++]; if (result == null) { result = factory.newInstance(); putInPool(result); ++nextAvailable; } } return result; } protected void putInPool(Object object) { synchronized (mutex) { pool[--nextAvailable] = object; mutex.notify(); } } private Object readResolve() { mutex = new Object(); return this; }}
线程安全的SimpleDateFormat的实现如下(同样出自XStream包):
public class ThreadSafeSimpleDateFormat { private final String formatString; private final Pool pool; public ThreadSafeSimpleDateFormat(String format, int initialPoolSize, int maxPoolSize, final boolean lenient) { formatString = format; pool = new Pool(initialPoolSize, maxPoolSize, new Pool.Factory() { public Object newInstance() { SimpleDateFormat dateFormat = new SimpleDateFormat(formatString, Locale.ENGLISH); dateFormat.setLenient(lenient); return dateFormat; } }); } public String format(Date date) { DateFormat format = fetchFromPool(); try { return format.format(date); } finally { pool.putInPool(format); } } public Date parse(String date) throws ParseException { DateFormat format = fetchFromPool(); try { return format.parse(date); } finally { pool.putInPool(format); } } private DateFormat fetchFromPool() { TimeZone tz = TimeZone.getDefault(); DateFormat format = (DateFormat)pool.fetchFromPool(); if (!tz.equals(format.getTimeZone())) { format.setTimeZone(tz); } return format; }}
0 0
- 一个简单的Java对象池实现——可用来解决SimpleDateFormat的线程安全问题
- java 解决simpledateformat线程安全问题
- SimpleDateFormat的线程安全问题
- SimpleDateFormat的线程安全问题
- SimpleDateFormat的线程安全问题
- SimpleDateFormat 的线程安全问题
- 使用Threadlocal来解决SimpleDateFormat的多线程安全问题
- ThreadLocal解决SimpleDateFormat线程安全问题
- SimpleDateFormat 的线程安全问题与解决方案
- SimpleDateFormat的线程安全问题与解决方案
- SimpleDateFormat的线程安全问题与解决方案
- SimpleDateFormat 的线程安全问题与解决方案
- SimpleDateFormat的线程安全问题与解决方案
- SimpleDateFormat的线程安全问题与解决方案
- SimpleDateFormat 的线程安全问题与解决方案
- SimpleDateFormat的线程安全问题与解决方案
- SimpleDateFormat 的线程安全问题与解决方案
- SimpleDateFormat 的线程安全问题与 ThreadLocal
- nginx使用ssl模块配置HTTPS支持
- 设置MyEclipse中代码的换行长度
- linux系统配置
- 模式识别(Pattern Recognition)学习笔记(三十二)-- 逻辑回归
- 前端开发部署
- 一个简单的Java对象池实现——可用来解决SimpleDateFormat的线程安全问题
- hexo和github更配
- 飛飛(七十三)阅读 STL中的简单容器和迭代器
- C3p0
- select模型
- 点击tabbar选项返回当前viewController最顶层
- j2ee13个规范总结
- 设置正确的线程数量
- 《教程要点》