java对象池化
来源:互联网 发布:淘宝店铺资质代表什么 编辑:程序博客网 时间:2024/05/26 20:23
对象池化技术
对象池化的基本思路是:将用过的对象保存起来,等下一次需要这种对象的时候,再拿出来重复使用,从而在一定程度上减少频繁创建对象所造成的开销。用于充当保存对象的“容器”的对象,被称为“对象池”(Object Pool,或简称Pool)。
对于没有状态的对象(例如String),在重复使用之前,无需进行任何处理;对于有状态的对象(例如StringBuffer),在重复使用之前,就需要把它们恢复到等同于刚刚生成时的状态。由于条件的限制,恢复某个对象的状态的操作不可能实现了的话,就得把这个对象抛弃,改用新创建的实例了。
并非所有对象都适合拿来池化——因为维护对象池也要造成一定开销。对生成时开销不大的对象进行池化,反而可能会出现“维护对象池的开销”大于“生成新对象的开销”,从而使性能降低的情况。但是对于生成时开销可观的对象,池化技术就是提高性能的有效策略了。
什么时候不要池化
采用对象池化的本意,是要通过减少对象生成的次数,减少花在对象初始化上面的开销,从而提高整体的性能。然而池化处理本身也要付出代价,因此,并非任何情况下都适合采用对象池化。
对于类似Point这样的轻量级对象,进行池化处理后,性能反而下降,因此不宜池化;
对于类似Hashtable这样的中量级对象,进行池化处理后,性能基本不变,一般不必池化(池化会使代码变复杂,增大维护的难度);
对于类似JPanel这样的重量级对象,进行池化处理后,性能有所上升,可以考虑池化。
根据使用方法的不同,实际的情况可能与这一测量结果略有出入。在配置较高的机器和技术较强的虚拟机上,不宜池化的对象的范围可能会更大。不过,对于像网络和数据库连接这类重量级的对象来说,目前还是有池化的必要。
基本上,只在重复生成某种对象的操作成为影响性能的关键因素的时候,才适合进行对象池化。如果进行池化所能带来的性能提高并不重要的话,还是不采用对象池化技术,以保持代码的简明,而使用更好的硬件和更棒的虚拟机来提高性能为佳。
对象池化的基本思路是:将用过的对象保存起来,等下一次需要这种对象的时候,再拿出来重复使用,从而在一定程度上减少频繁创建对象所造成的开销。用于充当保存对象的“容器”的对象,被称为“对象池”(Object Pool,或简称Pool)。
对于没有状态的对象(例如String),在重复使用之前,无需进行任何处理;对于有状态的对象(例如StringBuffer),在重复使用之前,就需要把它们恢复到等同于刚刚生成时的状态。由于条件的限制,恢复某个对象的状态的操作不可能实现了的话,就得把这个对象抛弃,改用新创建的实例了。
并非所有对象都适合拿来池化——因为维护对象池也要造成一定开销。对生成时开销不大的对象进行池化,反而可能会出现“维护对象池的开销”大于“生成新对象的开销”,从而使性能降低的情况。但是对于生成时开销可观的对象,池化技术就是提高性能的有效策略了。
什么时候不要池化
采用对象池化的本意,是要通过减少对象生成的次数,减少花在对象初始化上面的开销,从而提高整体的性能。然而池化处理本身也要付出代价,因此,并非任何情况下都适合采用对象池化。
对于类似Point这样的轻量级对象,进行池化处理后,性能反而下降,因此不宜池化;
对于类似Hashtable这样的中量级对象,进行池化处理后,性能基本不变,一般不必池化(池化会使代码变复杂,增大维护的难度);
对于类似JPanel这样的重量级对象,进行池化处理后,性能有所上升,可以考虑池化。
根据使用方法的不同,实际的情况可能与这一测量结果略有出入。在配置较高的机器和技术较强的虚拟机上,不宜池化的对象的范围可能会更大。不过,对于像网络和数据库连接这类重量级的对象来说,目前还是有池化的必要。
基本上,只在重复生成某种对象的操作成为影响性能的关键因素的时候,才适合进行对象池化。如果进行池化所能带来的性能提高并不重要的话,还是不采用对象池化技术,以保持代码的简明,而使用更好的硬件和更棒的虚拟机来提高性能为佳。
在Java中可以自定义或者借用第三方类库(如:apache commons-pool)实现对象池
以下是我自己实现的对象池,相当粗糙
思路是:
线程池中有两个集合,一个集合A存放空闲中的对象,一个集合B存放使用中的对象,
线程从A中拿到对象使用,并放入B中,当线程使用完对象之后从B中取出放回A中,
有状态的对象在使用之前先恢复为初始化状态,
当线程池中所有的对象都是使用中时(即都属于集合B),线程等待,当有线程返还对象时,线程唤醒。
001
package
common.pool;
002
003
import
java.lang.reflect.Field;
004
import
java.util.Collections;
005
import
java.util.HashSet;
006
import
java.util.Iterator;
007
import
java.util.Set;
008
009
/**
010
*
011
* @author JiaZhiTang
012
*自定义对象池
013
*/
014
@SuppressWarnings
({
"unchecked"
,
"hiding"
})
015
public
class
DIYObjectPool<E> {
016
private
Set<Object> activeSet = Collections.synchronizedSet(
new
HashSet<Object>());
//正在被使用的对象的集合,已被同步
017
private
Set<Object> idleSet = Collections.synchronizedSet(
new
HashSet<Object>());
//空闲的对象的集合,已被同步
018
019
private
Integer maxObjetc =
100
;
//最大对象数,默认值100
020
private
Class<E> cls;
//对象池 的类,因为java不能 直接使用泛型创建对象 T t = new T();
021
private
Object lock =
new
Object();
//线程等待监视器
022
023
024
/**
025
* 构造方法
026
* @param maxObjetc
027
* @param cls
028
*/
029
public
DIYObjectPool(Integer maxObjetc, Class<E> cls) {
030
this
.maxObjetc = maxObjetc;
031
this
.cls = cls;
032
}
033
034
/**
035
* 从线程池中取出对象
036
* @param <E>
037
* @return
038
* @throws Exception
039
*/
040
public
synchronized
<E> E borrowObject()
throws
Exception{
041
Object obj =
null
;
042
if
(idleSet.size()>
0
){
043
Iterator<Object> iterator = idleSet.iterator();
044
obj = iterator.next();
045
}
046
if
(obj !=
null
){
047
idleSet.remove(obj);
048
activeSet.add(obj);
049
}
else
{
050
int
size = activeSet.size()+idleSet.size();
051
if
(size>=maxObjetc){
052
synchronized
(lock) {
053
System.out.println(
"-----池中无对象,线程等待-----"
);
054
lock.wait();
055
}
056
return
borrowObject();
057
}
else
{
058
obj = cls.newInstance();
059
activeSet.add(obj);
060
}
061
}
062
063
System.out.println(
"池中总对象数: "
+(activeSet.size()+idleSet.size())+
" ,使用中:"
+activeSet.size()+
" ,空闲中:"
+idleSet.size());
064
065
clearObject(obj);
//有状态对象恢复默认初始化
066
return
(E)obj;
067
}
068
069
/**
070
* 对象使用完毕,返还线程池
071
* @param obj
072
*/
073
public
void
returnObject(Object obj){
074
if
(obj !=
null
){
075
activeSet.remove(obj);
076
idleSet.add(obj);
077
synchronized
(lock) {
078
System.out.println(
"唤醒等待线程"
);
079
lock.notify();
080
// lock.notifyAll();
081
}
082
083
}
084
}
085
086
087
/**
088
* 有状态对象恢复默认初始化
089
* @param obj
090
*/
091
public
void
clearObject(Object obj)
throws
Exception{
092
Class<?> cls = obj.getClass();
093
Field[] fields = cls.getDeclaredFields();
094
for
(Field field : fields) {
095
field.setAccessible(
true
);
096
field.set(obj,
null
);
097
}
098
}
099
100
101
public
static
void
main(String[] args)
throws
Exception {
102
//初始化线程池
103
int
max =
1000
;
104
DIYObjectPool<Object> pool =
new
DIYObjectPool<Object>(max,Object.
class
);
105
106
//自定义运行线程
107
class
TestThread
extends
Thread{
108
DIYObjectPool objectPool;
109
110
public
TestThread(DIYObjectPool objectPool) {
111
this
.objectPool = objectPool;
112
}
113
114
@Override
115
public
void
run() {
116
try
{
117
Object obj = objectPool.borrowObject();
118
Thread.sleep(
3000
);
//假设对象被一个线程使用的3秒钟
119
objectPool.returnObject(obj);
120
}
catch
(Exception e) {
121
e.printStackTrace();
122
}
123
}
124
}
125
126
//并发max*2个线程
127
max = max*
2
;
128
for
(
int
i =
0
; i < max; i++) {
129
new
TestThread(pool).start();
130
}
131
}
132
133
}
工厂类
01
package
common.pool;
02
03
import
org.apache.commons.pool.PoolableObjectFactory;
04
05
@SuppressWarnings
({
"unchecked"
})
06
public
class
ObjectPoolFactory
implements
PoolableObjectFactory {
07
08
private
Class cls;
09
private
static
final
String INIT_METHOD =
"clearObject"
;
//有状态对象恢复初始化的方法
10
11
12
public
ObjectPoolFactory(Class cls) {
13
this
.cls = cls;
14
}
15
16
public
void
activateObject(Object arg0)
throws
Exception {
17
System.out.println(
"有状态对象恢复初始化"
);
18
try
{
19
cls.getDeclaredMethod(INIT_METHOD).invoke(arg0);
//有状态对象恢复初始化
20
}
catch
(Exception e) {
21
}
22
}
23
24
public
void
destroyObject(Object arg0)
throws
Exception {
25
26
}
27
28
public
Object makeObject()
throws
Exception {
29
System.out.println(
"创建新对象"
);
30
return
cls.newInstance();
//创建新对象
31
}
32
33
public
void
passivateObject(Object arg0)
throws
Exception {
34
35
}
36
37
public
boolean
validateObject(Object arg0) {
38
return
false
;
39
}
40
41
}
对象池
01
package
common.pool;
02
03
import
org.apache.commons.pool.impl.GenericObjectPool;
04
05
06
@SuppressWarnings
({
"unchecked"
})
07
public
class
ObjectPool {
08
09
private
GenericObjectPool pool;
10
11
public
ObjectPool(Class cls) {
12
this
.pool =
new
GenericObjectPool(
new
ObjectPoolFactory(cls));
13
pool.setMaxActive(
2
);
//最大活动对象
14
pool.setMaxIdle(
1
);
//最大空闲对象
15
pool.setMaxWait(
100000
);
//最大等待时间
16
}
17
18
/**
19
* 池中取出对象
20
* @param <T>
21
* @return
22
*/
23
public
<T> T borrowObject(){
24
T obj =
null
;
25
try
{
26
obj = (T)pool.borrowObject();
27
System.out.println(
"获得对象"
);
28
}
catch
(Exception e) {
29
System.out.println(e);
30
}
31
return
obj;
32
}
33
34
/**
35
* 对象放回池中
36
* @param obj
37
*/
38
public
void
returnObject(Object obj){
39
try
{
40
pool.returnObject(obj);
41
System.out.println(
"返还对象"
);
42
}
catch
(Exception e) {
43
System.out.println(e);
44
}
45
}
46
47
}
测试
01
package
common.pool;
02
03
public
class
Test {
04
05
public
static
ObjectPool pool =
new
ObjectPool(Object.
class
);
06
07
public
static
void
main(String[] args) {
08
for
(
int
i =
0
; i <
2000
; i++) {
09
new
Thread(){
10
public
void
run() {
11
Object obj = Test.pool.borrowObject();
12
System.out.println(obj.toString());
13
try
{
14
Thread.sleep(
1000
);
15
}
catch
(Exception e) {
16
}
17
Test.pool.returnObject(obj);
18
};
19
}.start();
20
}
21
}
22
23
}
这里依赖于 commons-pool-1.5.6.jar
- java对象池化
- java对象池化技术
- java实现对象池
- Java对象池技术
- java对象池ObjectPool
- java对象池ObjectPool
- java对象池技术
- JAVA对象池
- Java对象池
- JAVA 对象池
- Java对象池示例
- Java之对象池
- JAVA 对象池
- Java对象池示例
- java对象池示例
- Java之对象池
- 【对象池】 JAVA
- Java对象池
- ZOJ 1402 Magnificent Meatballs
- JDBC的驱动包下载总汇
- 【C/C++】 TC Graphics.h 图形编程 32位系统运行错误解决方案
- ZOJ 1201 Inversion
- VC++中复制构造函数与 CPtrArray 类
- java对象池化
- ubuntu下打开txt文件乱码的解决
- 程序设计入门经典
- POJ_1035题解
- 天勤OJ 题目1135: 素数
- HRBEU Max Use Of CPU(01背包)
- Java对象池技术的原理及其实现
- Linux设备驱动程序:gnu make 扩展语法
- HRBEU 油田合并