通常, 性能是软件开发和对象创建过程中的关键问题, 这可能是一个昂贵的步骤。
对象池模式说“重用创建昂贵的对象”。
基本上, 对象池是一个包含指定数量的对象的容器。从池中获取对象时, 在将对象放回之前, 该对象在池中不可用。池中的对象具有生命周期:创建, 验证和销毁。
池有助于更好地管理可用资源。有许多使用示例:特别是在应用程序服务器中, 有数据源池, 线程池等。
对象池设计模式的优势
- 它显着提高了应用程序的性能。
- 在初始化类实例的速率很高的情况下, 这是最有效的。
- 它管理连接并提供重用和共享它们的方法。
- 它还可以为可以创建的最大对象数提供限制。
用法:
- 当应用程序需要创建昂贵的对象时。例如:需要为数据库打开太多的连接, 那么创建新的连接将花费太长时间, 并且数据库服务器将过载。
- 当有多个客户端在不同时间需要相同的资源时。
注意:对象池设计模式本质上在服务器的Web容器中用于创建线程池和数据源池以处理请求。
对象池模式的示例:
让我们通过给定的UML图了解示例。
对象池模式的UML
以上UML的实现:
步骤1
创建一个用于创建对象数的ObjectPool类。
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public abstract class ObjectPool<T> {
/*
pool implementation is based on ConcurrentLinkedQueue from the java.util.concurrent package.
ConcurrentLinkedQueue is a thread-safe queue based on linked nodes.
Because the queue follows FIFO technique (first-in-first-out).
*/
private ConcurrentLinkedQueue<T> pool;
/*
ScheduledExecutorService starts a special task in a separate thread and observes
the minimum and maximum number of objects in the pool periodically in a specified
time (with parameter validationInterval).
When the number of objects is less than the minimum, missing instances will be created.
When the number of objects is greater than the maximum, too many instances will be removed.
This is sometimes useful for the balance of memory consuming objects in the pool.
*/
private ScheduledExecutorService executorService;
/*
* Creates the pool.
*
* @param minObjects : the minimum number of objects residing in the pool
*/
public ObjectPool(final int minObjects)
{
// initialize pool
initialize(minObjects);
}
/*
Creates the pool.
@param minObjects: minimum number of objects residing in the pool.
@param maxObjects: maximum number of objects residing in the pool.
@param validationInterval: time in seconds for periodical checking of
minObjects / maxObjects conditions in a separate thread.
When the number of objects is less than minObjects, missing instances will be created.
When the number of objects is greater than maxObjects, too many instances will be removed.
*/
public ObjectPool(final int minObjects, final int maxObjects, final long validationInterval) {
// initialize pool
initialize(minObjects);
// check pool conditions in a separate thread
executorService = Executors.newSingleThreadScheduledExecutor();
executorService.scheduleWithFixedDelay(new Runnable() // annonymous class
{
@Override
public void run() {
int size = pool.size();
if (size < minObjects) {
int sizeToBeAdded = minObjects + size;
for (int i = 0; i < sizeToBeAdded; i++) {
pool.add(createObject());
}
} else if (size > maxObjects) {
int sizeToBeRemoved = size - maxObjects;
for (int i = 0; i < sizeToBeRemoved; i++) {
pool.poll();
}
}
}
}, validationInterval, validationInterval, TimeUnit.SECONDS);
}
/*
Gets the next free object from the pool. If the pool doesn't contain any objects, a new object will be created and given to the caller of this method back.
@return T borrowed object
*/
public T borrowObject() {
T object;
if ((object = pool.poll()) == null)
{
object = createObject();
}
return object;
}
/*
Returns object back to the pool.
@param object object to be returned
*/
public void returnObject(T object) {
if (object == null) {
return;
}
this.pool.offer(object);
}
/*
Shutdown this pool.
*/
public void shutdown(){
if (executorService != null){
executorService.shutdown();
}
}
/*
Creates a new object.
@return T new object
*/
protected abstract T createObject();
private void initialize(final int minObjects) {
pool = new ConcurrentLinkedQueue<T>();
for (int i = 0; i < minObjects; i++) {
pool.add(createObject());
}
}
}// End of the ObjectPool Class.
第2步
创建一个ExportingProcess类, ExportingTask类将使用该类。
public class ExportingProcess {
private long processNo;
public ExportingProcess(long processNo) {
this.processNo = processNo;
// do some expensive calls / tasks here in future
// .........
System.out.println("Object with process no. " + processNo + " was created");
}
public long getProcessNo() {
return processNo;
}
}// End of the ExportingProcess class.
第三步
创建一个ExportingTask类, 它将使用ExportingProcess和ObjectPool类。
public class ExportingTask implements Runnable {
private ObjectPool<ExportingProcess> pool;
private int threadNo;
public ExportingTask(ObjectPool<ExportingProcess> pool, int threadNo){
this.pool = pool;
this.threadNo = threadNo;
}
public void run() {
// get an object from the pool
ExportingProcess exportingProcess = pool.borrowObject();
System.out.println("Thread " + threadNo + ": Object with process no. "
+ exportingProcess.getProcessNo() + " was borrowed");
//you can do something here in future
// .........
// return ExportingProcess instance back to the pool
pool.returnObject(exportingProcess);
System.out.println("Thread " + threadNo +": Object with process no. "
+ exportingProcess.getProcessNo() + " was returned");
}
}// End of the ExportingTask class.
步骤4
创建一个ObjectPoolDemo类。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
public class ObjectPoolDemo{
private ObjectPool<ExportingProcess> pool;
private AtomicLong processNo=new AtomicLong(0);
public void setUp() {
// Create a pool of objects of type ExportingProcess.
/*Parameters:
1) Minimum number of special ExportingProcess instances residing in the pool = 4
2) Maximum number of special ExportingProcess instances residing in the pool = 10
3) Time in seconds for periodical checking of minObjects / maxObjects conditions
in a separate thread = 5.
-->When the number of ExportingProcess instances is less than minObjects, missing instances will be created.
-->When the number of ExportingProcess instances is greater than maxObjects, too many instances will be removed.
-->If the validation interval is negative, no periodical checking of
minObjects / maxObjects conditions in a separate thread take place.
These boundaries are ignored then.
*/
pool = new ObjectPool<ExportingProcess>(4, 10, 5)
{
protected ExportingProcess createObject()
{
// create a test object which takes some time for creation
return new ExportingProcess( processNo.incrementAndGet());
}
};
}
public void tearDown() {
pool.shutdown();
}
public void testObjectPool() {
ExecutorService executor = Executors.newFixedThreadPool(8);
// execute 8 tasks in separate threads
executor.execute(new ExportingTask(pool, 1));
executor.execute(new ExportingTask(pool, 2));
executor.execute(new ExportingTask(pool, 3));
executor.execute(new ExportingTask(pool, 4));
executor.execute(new ExportingTask(pool, 5));
executor.execute(new ExportingTask(pool, 6));
executor.execute(new ExportingTask(pool, 7));
executor.execute(new ExportingTask(pool, 8));
executor.shutdown();
try {
executor.awaitTermination(30, TimeUnit.SECONDS);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
public static void main(String args[]) {
ObjectPoolDemo op=new ObjectPoolDemo();
op.setUp();
op.tearDown();
op.testObjectPool();
}
}//End of the ObjectPoolDemo class.
评论前必须登录!
注册