对象池

涉及到的

1)stack>vector>list

2)工厂模式, 单例模式

3)线程同步

4)泛型

5)反射

为什么要将对象池话,这个问题还是比较有意义的。我们知道,一个对象的生命周期包括:创建、使用、销毁(类比Servlet的生命周期)。实际上创建和使用之间还有一个初始化的过程,只不过java把初始化和创建这两步结合在了一起(思考题:为什么要这样设计java,这是如何实现的?)。
到了这里,我们会发现,真正我们关注的是对象的使用,而创建和销毁是为了适用对象而产生的额外开销,通常来讲,这个开销很小,可以忽略不计。但是如果一个程序中设计到很多的对象创建,并且创建时间比较长的话,那我们就会很明显的感觉到这部分所造成的系统速度受限。

到了这里,大家都会理解了池化的意义,就是对象使用完不销毁,而是存放起来,等着系统再次需要的时候直接拿出来。其思想就是这样:创建一次,使用多次,以空间换取时间。
注意到了有木有!“以空间换取时间”这种思想存在于程序设计的方方面面,不只是只有算法那些高大上的领域才用得到。

到了这里,可能大家都发现池化这么好。但是细心的人会考虑:那池化也是有代价的,它也是有时间和空间开销的。我为了解决刚才的问题而引入了新的开销,到底值不值?这是个很好的问题。
“对于类似Point这样的轻量级对象,进行池化处理后,性能反而下降,因此不宜池化;对于类似Hashtable这样的中量级对象,进行池化处理后,性能基本不变,一般不必池化(池化会使代码变复杂,增大维护的难度);对于类似JPanel这样的重量级对象,进行池化处理后,性能有所上升,可以考虑池化。

public class ObjectPool<T> {

	private Stack<T> stack = new Stack<>();
	private Integer minSize = 3;
	private Integer maxSize = 10;
	private Integer usedSize = 0;
	private String classpath;
	

	/**
	 * 考虑三种情况: stack中有object; stack中没有object,但是可以创建; stack中没有object,不能创建,只能等待归还
	 */
	public T getInstance() {
		T t = null;
		synchronized (stack) {
			if (stack.size() > 0) {
				t = stack.pop();
				usedSize++;
			} else if (usedSize < maxSize) {
				try {
					t = (T) Class.forName(classpath).newInstance();
					usedSize++;
				} catch (InstantiationException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (ClassNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			// 当前要获取对象的线程等待,等待stack中有对象归还
			else {
				try {
					stack.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				// 注意这里如果使用t = stack.pop()在线程调用多的情况下可能报错
				t = getInstance();
			}
		}

		return t;
	}

	public void returnInstance(T t) {
		//对象归还时是否要对对象做初始化
		synchronized(stack) {
			stack.push(t);
			usedSize--;
			stack.notify();
		}
	}
	
	public Integer getMinSize() {
		return minSize;
	}

	public void setMinSize(Integer minSize) {
		this.minSize = minSize;
	}

	public Integer getMaxSize() {
		return maxSize;
	}

	public void setMaxSize(Integer maxSize) {
		this.maxSize = maxSize;
	}

	public Integer getUsedSize() {
		return usedSize;
	}

	public void setUsedSize(Integer usedSize) {
		this.usedSize = usedSize;
	}

	public String getClasspath() {
		return classpath;
	}

	public void setClasspath(String classpath) {
		this.classpath = classpath;
	}

}
public class TestMain {

	public static void main(String[] args) {
		ObjectPool<String> ss = new ObjectPool<>();
		ss.setClasspath("java.lang.String");
		for(int i = 0; i<20; i++) {
			new Thread(new InnerThread(ss)).start();
		}
		
	}
	
	static class InnerThread implements Runnable {
		ObjectPool<String> ss;
		public InnerThread(ObjectPool<String> ss) {
			this.ss = ss;
		}
		@Override
		public void run() {
			// TODO Auto-generated method stub
			String s = ss.getInstance();
			s = Thread.currentThread().getName();
			System.out.println(s);
			try {
				TimeUnit.SECONDS.sleep(10);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			s=null;
			ss.returnInstance(s);
			
		}
		
	}
	
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值