You are on page 1of 8

2.

8 OBJECT POOL PATTERN


Mostly, performance is the key issue during the software development and the object
creation, which may be a costly step.
Object Pool Pattern says that " to reuse the object that are expensive to create".
Basically, an Object pool is a container which contains a specified amount of objects.
When an object is taken from the pool, it is not available in the pool until it is put
back. Objects in the pool have a lifecycle: creation, validation and destroy.
A pool helps to manage available resources in a better way. There are many using
examples: especially in application servers there are data source pools, thread pools etc.
ADVANTAGE OF OBJECT POOL DESIGN PATTERN
o It boosts the performance of the application significantly.
o It is most effective in a situation where the rate of initializing a class instance is high.
o It manages the connections and provides a way to reuse and share them.
o It can also provide the limit for the maximum number of objects that can be created.
USAGE:
o When an application requires objects which are expensive to create. Eg: there is a
need of opening too many connections for the database then it takes too longer to
create a new one and the database server will be overloaded.
o When there are several clients who need the same resource at different times.
EXAMPLE OF OBJECT POOL PATTERN:
Let's understand the example by the given UML diagram.
UML for Object Pool Pattern
IMPLEMENTATION OF ABOVE UML:
Step 1
Create an ObjectPool class that is used to create the number of objects.
File: ObjectPool.java
1. import java.util.concurrent.ConcurrentLinkedQueue;  
2. import java.util.concurrent.Executors;  
3. import java.util.concurrent.ScheduledExecutorService;  
4. import java.util.concurrent.TimeUnit;  
5.   
6. public abstract class ObjectPool<T> {  
7. /* 
8.   pool implementation is based on ConcurrentLinkedQueue from the java.util.concurre
nt package. 
9.   ConcurrentLinkedQueue is a thread-safe queue based on linked nodes.  
10.    Because the queue follows FIFO technique (first-in-first-out). 
11.  */          
12.       
13.    private ConcurrentLinkedQueue<T> pool;  
14.          
15.  /*  
16.    
17.    ScheduledExecutorService starts a special task in a separate thread and observes 
18.    the minimum and maximum number of objects in the pool periodically in a specifie
d  
19.     time (with parameter validationInterval).  
20.    When the number of objects is less than the minimum, missing instances will be cre
ated.  
21.    When the number of objects is greater than the maximum, too many instances will b
e removed.  
22.    This is sometimes useful for the balance of memory consuming objects in the pool. 
23. */  
24.     private ScheduledExecutorService executorService;  
25.        /* 
26.      * Creates the pool. 
27.      * 
28.      * @param minObjects : the minimum number of objects residing in the pool 
29.      */  
30.        
31.     public ObjectPool(final int minObjects)   
32.     {  
33.         // initialize pool  
34.           
35.         initialize(minObjects);  
36.           
37.     }  
38.       
39.     /* 
40.       Creates the pool. 
41.       @param minObjects:   minimum number of objects residing in the pool. 
42.       @param maxObjects:   maximum number of objects residing in the pool. 
43.       @param validationInterval: time in seconds for periodical checking of  
44.          minObjects / maxObjects conditions in a separate thread. 
45.       When the number of objects is less than minObjects, missing instances will be cre
ated. 
46.       When the number of objects is greater than maxObjects, too many instances will b
e removed. 
47.     */  
48.      public ObjectPool(final int minObjects, final int maxObjects, final long validatio
nInterval) {  
49.         // initialize pool  
50.          initialize(minObjects);  
51.           // check pool conditions in a separate thread  
52.         executorService = Executors.newSingleThreadScheduledExecutor();  
53.         executorService.scheduleWithFixedDelay(new Runnable()  // annonymous class  
54.         {  
55.             @Override  
56.             public void run() {  
57.                 int size = pool.size();  
58.                  
59.                 if (size < minObjects) {  
60.                     int sizeToBeAdded = minObjects + size;  
61.                     for (int i = 0; i < sizeToBeAdded; i++) {  
62.                         pool.add(createObject());  
63.                     }  
64.                 } else if (size > maxObjects) {  
65.                     int sizeToBeRemoved = size - maxObjects;  
66.                     for (int i = 0; i < sizeToBeRemoved; i++) {  
67.                         pool.poll();  
68.                     }  
69.                 }  
70.             }  
71.         }, validationInterval, validationInterval, TimeUnit.SECONDS);  
72.     }  
73.       
74.   /* 
75.       Gets the next free object from the pool. If the pool doesn't contain any objects, 
76.       a new object will be created and given to the caller of this method back. 
77.       
78.       @return T borrowed object 
79.   */  
80.     public T borrowObject() {  
81.         T object;  
82.         if ((object = pool.poll()) == null)  
83.         {  
84.             object = createObject();  
85.         }  
86.         return object;  
87.     }  
88.  /* 
89.       Returns object back to the pool. 
90.       @param object object to be returned 
91.   */  
92.     public void returnObject(T object) {  
93.         if (object == null) {  
94.             return;  
95.         }  
96.         this.pool.offer(object);  
97.     }  
98.    /* 
99.         Shutdown this pool. 
100.     */  
101.       public void shutdown(){  
102.         if (executorService != null){  
103.             executorService.shutdown();  
104.         }  
105.     }  
106.     /* 
107.         Creates a new object. 
108.          @return T new object 
109.      */  
110.     protected abstract T createObject();  
111.   
112.     private void initialize(final int minObjects)  {  
113.         pool = new ConcurrentLinkedQueue<T>();  
114.         for (int i = 0; i < minObjects; i++) {  
115.             pool.add(createObject());  
116.         }  
117.     }  
118. }// End of the ObjectPool Class.  
Step 2
Create an ExportingProcess class that will be used by ExportingTask class.
File: ExportingProcess.java
1. public class ExportingProcess {  
2.  private long processNo;  
3.   
4.     public ExportingProcess(long processNo)  {  
5.          this.processNo = processNo;  
6.         // do some  expensive calls / tasks here in future  
7.         // .........  
8.       System.out.println("Object with process no. " + processNo + " was created");  
9.      }  
10.      
11.     public long getProcessNo() {  
12.         return processNo;  
13.     }  
14. }// End of the ExportingProcess class.  
Step 3
Create an ExportingTask class that will use ExportingProcess and ObjectPool class.
File: ExportingTask.java
1. public class ExportingTask implements Runnable {  
2.         private ObjectPool<ExportingProcess> pool;  
3.         private int threadNo;  
4.         public ExportingTask(ObjectPool<ExportingProcess> pool, int threadNo){  
5.             this.pool = pool;  
6.             this.threadNo = threadNo;  
7.         }  
8.       
9.         public void run() {  
10.             // get an object from the pool  
11.             ExportingProcess exportingProcess = pool.borrowObject();  
12.             System.out.println("Thread " + threadNo + ": Object with process no. "  
13.                     + exportingProcess.getProcessNo() + " was borrowed");  
14.   
15.             //you can  do something here in future  
16.             // .........  
17.   
18.                // return ExportingProcess instance back to the pool  
19.             pool.returnObject(exportingProcess);  
20.   
21.             System.out.println("Thread " + threadNo +": Object with process no. "  
22.                    + exportingProcess.getProcessNo() + " was returned");  
23.         }  
24.   
25.     }// End of the ExportingTask class.   
Step 4
Create an ObjectPoolDemo class.
File: ObjectPoolDemo.java
1. import java.util.concurrent.ExecutorService;  
2. import java.util.concurrent.Executors;  
3. import java.util.concurrent.TimeUnit;  
4. import java.util.concurrent.atomic.AtomicLong;  
5. public class ObjectPoolDemo{  
6.       private ObjectPool<ExportingProcess> pool;  
7.       private AtomicLong processNo=new AtomicLong(0);  
8.       public void setUp() {  
9.             // Create a pool of objects of type ExportingProcess.  
10.            /*Parameters: 
11.              1) Minimum number of special ExportingProcess instances residing in the po
ol = 4 
12.              2) Maximum number of special ExportingProcess instances residing in the po
ol = 10 
13.              3) Time in seconds for periodical checking of minObjects / maxObjects condi
tions 
14.                 in a separate thread = 5. 
15.              -->When the number of ExportingProcess instances is less than minObjects,  
16.                  missing instances will be created. 
17.              -->When the number of ExportingProcess instances is greater than maxObject
s, 
18.                   too many instances will be removed. 
19.             -->If the validation interval is negative, no periodical checking of  
20.                   minObjects / maxObjects conditions in a separate thread take place. 
21.               These boundaries are ignored then. 
22.            */  
23.       pool = new ObjectPool<ExportingProcess>(4, 10, 5)  
24.         {  
25.             protected ExportingProcess createObject()  
26.             {  
27.                 // create a test object which takes some time for creation  
28.                 return new ExportingProcess( processNo.incrementAndGet());  
29.             }  
30.         };  
31.     }  
32.     public void tearDown() {  
33.         pool.shutdown();  
34.     }  
35.     public void testObjectPool() {  
36.         ExecutorService executor = Executors.newFixedThreadPool(8);  
37.   
38.         // execute 8 tasks in separate threads  
39.           
40.         executor.execute(new ExportingTask(pool, 1));  
41.         executor.execute(new ExportingTask(pool, 2));  
42.         executor.execute(new ExportingTask(pool, 3));  
43.         executor.execute(new ExportingTask(pool, 4));  
44.         executor.execute(new ExportingTask(pool, 5));  
45.         executor.execute(new ExportingTask(pool, 6));  
46.         executor.execute(new ExportingTask(pool, 7));  
47.         executor.execute(new ExportingTask(pool, 8));  
48.   
49.         executor.shutdown();  
50.         try {  
51.             executor.awaitTermination(30, TimeUnit.SECONDS);  
52.             } catch (InterruptedException e)  
53.               
54.               {  
55.                e.printStackTrace();  
56.               }  
57.     }  
58.     public static void main(String args[])  {   
59.         ObjectPoolDemo op=new ObjectPoolDemo();  
60.         op.setUp();  
61.         op.tearDown();  
62.         op.testObjectPool();  
63.    }   
64. }//End of the ObjectPoolDemo class.  
OUTPUT

You might also like