技术开发 频道

用Java实现多线程服务器程序

  对象池的构造和管理可以按照多种方式实现。最灵活的方式是将池化对象的Class类型在对象池之外指定,即在ObjectPoolFactory类创建对象池时,动态指定该对象池所池化对象的Class类型,其实现代码如下:

1 . . .
2
3   public ObjectPool createPool(ParameterObject paraObj,Class clsType) {
4
5   return new ObjectPool(paraObj, clsType);
6
7   }
8
9   . . .
10
11

  其中,paraObj参数用于指定对象池的特征属性,clsType参数则指定了该对象池所存放对象的类型。对象池(ObjectPool)创建以后,下面就是利用它来管理对象了,具体实现如下:

1 public class ObjectPool {
2  private ParameterObject paraObj;//该对象池的属性参数对象
3  private Class clsType;//该对象池中所存放对象的类型
4  private int currentNum = 0; //该对象池当前已创建的对象数目
5  private Object currentObj;//该对象池当前可以借出的对象
6  private Vector pool;//用于存放对象的池
7  public ObjectPool(ParameterObject paraObj, Class clsType) {
8   this.paraObj = paraObj;
9   this.clsType = clsType;
10   pool = new Vector();
11  }
12  public Object getObject() {
13   if (pool.size() <= paraObj.getMinCount()) {
14    if (currentNum <= paraObj.getMaxCount()) {
15     //如果当前池中无对象可用,而且已创建的对象数目小于所限制的最大值,就利用
16     //PoolObjectFactory创建一个新的对象
17     PoolableObjectFactory objFactory =PoolableObjectFactory.getInstance();
18     currentObj = objFactory.create Object (clsType);
19     currentNum++;
20    } else {
21     //如果当前池中无对象可用,而且所创建的对象数目已达到所限制的最大值,
22     //就只能等待其它线程返回对象到池中
23     synchronized (this) {
24      try {
25       wait();
26      } catch (InterruptedException e) {
27       System.out.println(e.getMessage());
28       e.printStackTrace();
29      }
30      currentObj = pool.firstElement();
31     }
32    }
33   } else {
34    //如果当前池中有可用的对象,就直接从池中取出对象
35    currentObj = pool.firstElement();
36   }
37   return currentObj;
38 }
39   public void returnObject(Object obj) {
40    // 确保对象具有正确的类型
41    if (obj.isInstance(clsType)) {
42     pool.addElement(obj);
43     synchronized (this) {
44      notifyAll();
45     }
46    } else {
47     throw new IllegalArgumentException("该对象池不能存放指定的对象类型");
48    }
49   }
50 }

  从上述代码可以看出,ObjectPool利用一个java.util.Vector作为可扩展的对象池,并通过它的构造函数来指定池化对象的Class类型及对象池的一些属性。在有对象返回到对象池时,它将检查对象的类型是否正确。当对象池里不再有可用对象时,它或者等待已被使用的池化对象返回池中,或者创建一个新的对象实例。不过,新对象实例的创建并不在ObjectPool类中,而是由PoolableObjectFactory类的createObject方法来完成的,具体实现如下:

1 . . .
2 public Object createObject(Class clsType) {
3  Object obj = null;
4  try {
5   obj = clsType.newInstance();
6  } catch (Exception e) {
7   e.printStackTrace();
8  }
9  return obj;
10 }
11 . . .

   这样,通用对象池的实现就算完成了,下面再看看客户端(Client)如何来使用它,假定池化对象的Class类型为StringBuffer:

1 . . .
2 //创建对象池工厂
3 ObjectPoolFactory poolFactory = ObjectPoolFactory. getInstance ();
4 //定义所创建对象池的属性
5 ParameterObject paraObj = new ParameterObject(2,1);
6 //利用对象池工厂,创建一个存放StringBuffer类型对象的对象池
7 ObjectPool pool = poolFactory.createPool(paraObj,String Buffer.class);
8 //从池中取出一个StringBuffer对象
9 StringBuffer buffer = (StringBuffer)pool.getObject();
10 //使用从池中取出的StringBuffer对象
11 buffer.append("hello");
12 System.out.println(buffer.toString());
13 . . .

  可以看出,通用对象池使用起来还是很方便的,不仅可以方便地避免频繁创建对象的开销,而且通用程度高。但遗憾的是,由于需要使用大量的类型定型(cast)操作,再加上一些对Vector类的同步操作,使得它在某些情况下对性能的改进非常有限,尤其对那些创建周期比较短的对象。

0
相关文章