举例讲解Java设计模式中的对象池模式编程

时间:2021-10-25 05:47:42

定义
一个对象池是一组已经初始化过且可以使用的对象的集合,池的用户可以从池子中取得对象,对其进行操作处理,并在不需要时归还给池子而非销毁它。

若初始化、实例化的代价高,且有需求需要经常实例化,但每次实例化的数量较少的情况下,使用对象池可以获得显著的效能提升。从池子中取得对象的时间是可预测的,但新建一个实例所需的时间是不确定。

实现

举例讲解Java设计模式中的对象池模式编程

1. Reusable - 对象池中的对象,通常实例化代价比较高。
2. Client - 使用一个对象的实例。
3. ReusablePool - 管理对象的实例化,回收和销毁。

单个实例中主要的思想
1.一个栈,这里用stack
2.初始化方法,容器开启的时候可以预先创建池
3.创建实例的方法
4.提供从池中获得对象实例的方法
5.提供返回的方法,不返回后果很严重
6.控制请求等待时间的方法,过了一定的事件还没获得对象实例,就返回一个null指针

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
import java.util.Stack;
 
@SuppressWarnings("unchecked")
public class ObjectPool {
 
  public ObjectPool() {
  }
 
  private PoolParam poolParam;
 
  public void setPoolParam(PoolParam poolParam) {
    this.poolParam = poolParam;
  }
 
  // 当前总对象个数
  private int currentNum = 0;
 
  private Class clazz;
 
  public void setClazz(Class clazz) {
    this.clazz = clazz;
  }
 
  // 栈,用来存放对象,模拟一个池
  private Stack stack;
 
  public Stack getStack() {
    return stack;
  }
 
  public void setStack(Stack stack) {
    this.stack = stack;
  }
 
  // .................................................................
  // 等待超时的记数变量
  private int timeWait = 0;
 
  // .................................................................
 
  // 创建对象池
  public void initalPool(PoolParam poolParam, Class clazz) {
 
    this.setPoolParam(poolParam);
    this.setClazz(clazz);
 
    stack = new Stack();
 
    stack.clear();
 
    // System.out.println("obj..pool is initial...");
    // 生成配置最小对象数,并压入栈中
    try {
 
      for (int i = 0; i < poolParam.getMinObjectCount(); i++) {
 
        // 根据poolParam初始化对象池
        stack.push(clazz.newInstance());
      }
 
    } catch (InstantiationException e) {
      e.printStackTrace();
    } catch (IllegalAccessException e) {
      e.printStackTrace();
    }
 
  }
 
  // 创建单个对象
  private Object createObj(Class clazz) {
 
    Object obj = null;
    try {
 
      obj = clazz.newInstance();
 
      // System.out.println("a new one...");
    } catch (InstantiationException e) {
      e.printStackTrace();
    } catch (IllegalAccessException e) {
      e.printStackTrace();
    }
 
    return obj;
  }
 
  // 对象池提供的get方法
  public Object getInstance(){
 
    // System.out.println(stack.size());
 
    Object object = null;
 
    if (stack.size() == 0) {
 
      // 如果当前栈的长度为0,并且总的对象数没有超过定义最大数
      if ((currentNum + poolParam.getMinObjectCount()) < poolParam
          .getMaxObjectCount()) {
 
        // 新创建一个对象
        object = this.createObj(clazz);
        // 对象数+1
        currentNum++;
 
      } else {
 
        synchronized (this) {
 
          try {
            waitme(this);
          } catch (Exception e) {
            e.printStackTrace();
          }
 
          // 获得通知后检测栈中是为空,并给出刚刚释放的资源
          if (!stack.empty()) {
            object = stack.pop();
          }
        }
      }
 
    } else if (stack.size() > 0) {
 
      object = stack.pop();
 
      // System.out.println(stack.size());
    }
 
    return object;
  }
 
  // 返回对象的方法
  public void returnObj(Object obj) {
 
    if (clazz.isInstance(obj)) {
 
      stack.push(obj);
 
      synchronized (this) {
 
        notify();
      }
    } else {
      System.out.println("this object can not push to stack!");
    }
 
  }
 
  // 等待递归算法
  private void waitme(ObjectPool pool) {
 
    // 等待2s的技术控制
    if (timeWait >= 2000) {
      System.out.println("jump up this step..");
 
      timeWait = 0;
      return;
 
    } else {
 
      try {
 
        pool.wait(500);
 
        // 等待计数累加。。
        timeWait +=1000;
 
        System.out.println("waiting time to free obj..");
 
        if (stack.empty()) {
          System.out.println("agian....");
          waitme(pool);
        }
 
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }
 
}

 
管理池类,这个不是很难,同步了就好

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
@SuppressWarnings("unchecked")
public class ObjectPoolManage {
 
  private ObjectPoolManage() {
  }
 
  private static ObjectPool pool;
   
 
 
  // 实现一个单例的获取方法....默认
  public static synchronized ObjectPool getCacheObject(Class clazz) {
 
    if (null != pool) {
      return pool;
    } else {
 
      createObjectPool(null, clazz);
      return pool;
    }
 
  }
 
  // 实现一个单例的获取方法...自定义
 
  public static synchronized ObjectPool getCacheObject(PoolParam p, Class clazz) {
    if (null != pool) {
      return pool;
    } else {
 
      createObjectPool(p, clazz);
      return pool;
    }
 
  }
 
  private static ObjectPool createObjectPool(PoolParam p, Class clazz) {
 
    pool = new ObjectPool();
 
    if (null == p) {
      pool.initalPool(new PoolParam(5,10), clazz);
    } else {
      pool.initalPool(p, clazz);
    }
 
    return pool;
  }
   
  private static Class getclazz(){
     
    Class clazz=null;
     
    try {
      clazz= Class.forName(ppp.getPropertyByName("objectPath"));
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    }
     
    return clazz;
  }
}


相关问题和实现
1. 对象池中可以限制对象的个数,当超过限制时,对象池需要返回异常或者空值,以通知客户。
2. 在多线程环境中,在checkout和checkin方法需要同步。
3. 定时清理过期的对象。