/*
*Because of the penalty of the performance, We'd better try it in another way.
*
*A generic pool requires acccess to the internal state variables of the managed objects,
*so that the objects can be initialized for reuse.
* If we want to hide state information or make it immutable in our objects,
*We can solve both these problems by building the object pool into the actual object class,
*rather than making it a separate add-on.
*
*Note that: "Immutable" is only from user's standpoint.
*/
import java.util.*;
import java.awt.*;
public class ImmutableRectangle{
//Free pool capacity
private static final int FREE_POOL_SIZE = 40;
//Pool owned by class
private static final ImmutableRectangle[] freeStack = new ImmutableRectangle[FREE_POOL_SIZE];
private static int countFree;
//Intinsic states of the rectangle
private int xValue;
private int yValue;
private int widthValue;
private int heightValue;
private ImmutableRectangle(){}
public static synchronized ImmutableRectangle getInstance(int x, int y, int width, int height){
ImmutableRectangle result;
//Check if the pool is empty, create a new object if so
if (countFree ==0){
result = new ImmutableRectangle();
System.out.println("Create a new object.");
}
//Remove object from the end of free pool
else{
result = freeStack[--countFree];
System.out.println("Get instance from the free pool.");
}
//Initialize the object to the specified state.
result.xValue = x;
result.yValue = y;
result.widthValue = width;
result.heightValue = height;
return result;
}
public static ImmutableRectangle getInstance(int width, int height){
return getInstance(0, 0, width, height);
}
public static ImmutableRectangle getInstance(Point p, Dimension d){
return getInstance(p.x, p.y, d.width, d.height);
}
public static ImmutableRectangle getInstance(){
return getInstance(0, 0, 0, 0);
}
public static synchronized void freeInstance(ImmutableRectangle rect){
if (countFree < FREE_POOL_SIZE)
freeStack[countFree++] = rect;
}
public int getX(){
return xValue;
}
public int getY(){
return yValue;
}
public int getWidth(){
return widthValue;
}
public int getHeight(){
return heightValue;
}
public static int getCountFree(){
return countFree;
}
}
class ImmutableRectangleTest{
private int loopTimes = 100;
private class AnotherThread extends Thread{
public void run(){
for (int i = 0; i < loopTimes; i++){
ImmutableRectangle rect = ImmutableRectangle.getInstance(i, i, i, i);
//Do something with the object
//………………
//Return "immutable" rectangle to pool.
ImmutableRectangle.freeInstance(rect);
}
}
}
AnotherThread t = new AnotherThread();
public static void main(String[] args){
ImmutableRectangleTest irt = new ImmutableRectangleTest();
irt.t.start();
int loopTimes = 100;
for (int i = 0; i < loopTimes; i++){
ImmutableRectangle rect = ImmutableRectangle.getInstance(i, i, i, i);
//Do something with the object
//………………
//Return "immutable" rectangle to pool.
ImmutableRectangle.freeInstance(rect);
}
try{
irt.t.join();
}catch (InterruptedException e){}
System.out.println("The number of objects in the pool at last is " + ImmutableRectangle.getCountFree());
}
}