java对象池,java对象池化

对象池化技术 
 对象池化的基本思路是:将用过的对象保存起来,等下一次需要这种对象的时候,再拿出来重复使用,从而在一定程度上减少频繁创建对象所造成的开销。用于充当保存对象的“容器”的对象,被称为“对象池”(Object Pool,或简称Pool)。


 对于没有状态的对象(例如String),在重复使用之前,无需进行任何处理;对于有状态的对象(例如StringBuffer),在重复使用之前,就需要把它们恢复到等同于刚刚生成时的状态。由于条件的限制,恢复某个对象的状态的操作不可能实现了的话,就得把这个对象抛弃,改用新创建的实例了。


 并非所有对象都适合拿来池化——因为维护对象池也要造成一定开销。对生成时开销不大的对象进行池化,反而可能会出现“维护对象池的开销”大于“生成新对象的开销”,从而使性能降低的情况。但是对于生成时开销可观的对象,池化技术就是提高性能的有效策略了。




什么时候不要池化 
  采用对象池化的本意,是要通过减少对象生成的次数,减少花在对象初始化上面的开销,从而提高整体的性能。然而池化处理本身也要付出代价,因此,并非任何情况下都适合采用对象池化。




 对于类似Point这样的轻量级对象,进行池化处理后,性能反而下降,因此不宜池化;  


  对于类似Hashtable这样的中量级对象,进行池化处理后,性能基本不变,一般不必池化(池化会使代码变复杂,增大维护的难度);


   对于类似JPanel这样的重量级对象,进行池化处理后,性能有所上升,可以考虑池化。


   根据使用方法的不同,实际的情况可能与这一测量结果略有出入。在配置较高的机器和技术较强的虚拟机上,不宜池化的对象的范围可能会更大。不过,对于像网络和数据库连接这类重量级的对象来说,目前还是有池化的必要。


  基本上,只在重复生成某种对象的操作成为影响性能的关键因素的时候,才适合进行对象池化。如果进行池化所能带来的性能提高并不重要的话,还是不采用对象池化技术,以保持代码的简明,而使用更好的硬件和更棒的虚拟机来提高性能为佳。



在Java中可以自定义或者借用第三方类库(如:apache commons-pool)实现对象池

以下是我自己实现的对象池,相当粗糙

思路是:

线程池中有两个集合,一个集合A存放空闲中的对象,一个集合B存放使用中的对象,

线程从A中拿到对象使用,并放入B中,当线程使用完对象之后从B中取出放回A中,

有状态的对象在使用之前先恢复为初始化状态,

当线程池中所有的对象都是使用中时(即都属于集合B),线程等待,当有线程返还对象时,线程唤醒。

package common.pool;

import java.lang.reflect.Field;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

/**
 * 
 * @author JiaZhiTang
 *自定义对象池
 */
@SuppressWarnings({"unchecked","hiding"})
public class DIYObjectPool<E> {
	private  Set<Object> activeSet = Collections.synchronizedSet(new HashSet<Object>());//正在被使用的对象的集合,已被同步
	private  Set<Object> idleSet = Collections.synchronizedSet(new HashSet<Object>());//空闲的对象的集合,已被同步
	
	private Integer maxObjetc = 100;//最大对象数,默认值100
	private Class<E> cls;//对象池 的类,因为java不能 直接使用泛型创建对象   T t = new T();
	private Object lock = new Object();//线程等待监视器


	/**
	 * 构造方法
	 * @param maxObjetc
	 * @param cls
	 */
	public DIYObjectPool(Integer maxObjetc, Class<E> cls) {
		this.maxObjetc = maxObjetc;
		this.cls = cls;
	}

	/**
	 * 从线程池中取出对象
	 * @param <E>
	 * @return
	 * @throws Exception
	 */
	public synchronized <E> E borrowObject() throws Exception{
		Object obj = null;
		if(idleSet.size()>0){
			Iterator<Object> iterator = idleSet.iterator();
			obj = iterator.next();
		}
		if(obj != null){
			idleSet.remove(obj);
			activeSet.add(obj);
		}else{
			int size = activeSet.size()+idleSet.size();
			if(size>=maxObjetc){
				synchronized (lock) {
					System.out.println("-----池中无对象,线程等待-----");
					lock.wait();
				}
				return borrowObject();
			}else{
				obj = cls.newInstance();
				activeSet.add(obj);
			}
		}
		
		System.out.println("池中总对象数: "+(activeSet.size()+idleSet.size())+" ,使用中:"+activeSet.size()+" ,空闲中:"+idleSet.size());
		
		clearObject(obj);//有状态对象恢复默认初始化
		return (E)obj;
	}
	
	/**
	 * 对象使用完毕,返还线程池
	 * @param obj
	 */
	public void returnObject(Object obj){
		if(obj != null){
			activeSet.remove(obj);
			idleSet.add(obj);
			synchronized (lock) {
				System.out.println("唤醒等待线程");
				lock.notify();
//				lock.notifyAll();
			}
			
		}
	}


	/**
	 * 有状态对象恢复默认初始化
	 * @param obj
	 */
	public void clearObject(Object obj) throws Exception{
		Class<?> cls = obj.getClass();
		Field[] fields = cls.getDeclaredFields();
		for (Field field : fields) {
			field.setAccessible(true);
			field.set(obj, null);
        }
	}


	public static void main(String[] args) throws Exception {
		//初始化线程池
		int max = 1000;
		DIYObjectPool<Object> pool = new DIYObjectPool<Object>(max,Object.class);
		
		//自定义运行线程
		class TestThread extends Thread{
			DIYObjectPool objectPool;

			public TestThread(DIYObjectPool objectPool) {
				this.objectPool = objectPool;
			}
			
			@Override
			public void run() {
				try {
					Object obj = objectPool.borrowObject();
					Thread.sleep(3000);//假设对象被一个线程使用的3秒钟
					objectPool.returnObject(obj);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		
		//并发max*2个线程
		max = max*2;
		for (int i = 0; i < max; i++) {
			new TestThread(pool).start();
		}
	}
	
}


不过实际开发中还是借用第三方类库来得好,毕竟自己水平有限     (╯﹏╰)

工厂类

package common.pool;

import org.apache.commons.pool.PoolableObjectFactory;

@SuppressWarnings({"unchecked"})
public class ObjectPoolFactory implements PoolableObjectFactory {

	private Class cls;
	private static final String INIT_METHOD = "clearObject";//有状态对象恢复初始化的方法
	
	
	public ObjectPoolFactory(Class cls) {
		this.cls = cls;
	}

	public void activateObject(Object arg0) throws Exception {
		System.out.println("有状态对象恢复初始化");
		try {
			cls.getDeclaredMethod(INIT_METHOD).invoke(arg0);//有状态对象恢复初始化
		} catch (Exception e) {
		}
	}

	public void destroyObject(Object arg0) throws Exception {
		
	}

	public Object makeObject() throws Exception {
		System.out.println("创建新对象");
		return cls.newInstance();//创建新对象
	}

	public void passivateObject(Object arg0) throws Exception {
		
	}

	public boolean validateObject(Object arg0) {
		return false;
	}

}

对象池

package common.pool;

import org.apache.commons.pool.impl.GenericObjectPool;


@SuppressWarnings({"unchecked"})
public class ObjectPool {
	
	private GenericObjectPool pool;
	
	public ObjectPool(Class cls) {
		this.pool = new GenericObjectPool(new ObjectPoolFactory(cls));
		pool.setMaxActive(2);//最大活动对象
		pool.setMaxIdle(1);//最大空闲对象
		pool.setMaxWait(100000);//最大等待时间
	}
	
	/**
	 * 池中取出对象
	 * @param <T>
	 * @return
	 */
	public <T> T borrowObject(){
		T obj = null;
		try {
			obj = (T)pool.borrowObject();
			System.out.println("获得对象");
		} catch (Exception e) {
			System.out.println(e);
		}
		return obj;
	}
	
	/**
	 * 对象放回池中
	 * @param obj
	 */
	public void returnObject(Object obj){
		try {
			pool.returnObject(obj);
			System.out.println("返还对象");
		} catch (Exception e) {
			System.out.println(e);
		}
	}
	
}

测试

package common.pool;

public class Test {
	
	public static ObjectPool pool = new ObjectPool(Object.class);

	public static void main(String[] args) {
		for (int i = 0; i < 2000; i++) {
			new Thread(){
				public void run() {
					Object obj = Test.pool.borrowObject();
					System.out.println(obj.toString());
					try {
						Thread.sleep(1000);
					} catch (Exception e) {
					}
					Test.pool.returnObject(obj);
				};
			}.start();
		}
	}

}

这里依赖于  commons-pool-1.5.6.jar

你可能感兴趣的:(java对象池,java对象池化)