A very simple and generic Object Pooling pattern implementation.
Latest: v0.5.9 (Sept 9, 2020)
Please refer to release_note.md file
- Java 1.7 or later
- WAsys_Java_type_util
Implementation of a basic/generic Object Pooling(Interning) pattern in Java. Considering following characteristics of the implementation.
Object instancing is done when pool decides(based on its policy and state) to create an instance of Poolable_Object, and return it back to the caller. Since version 0.5.1, this repo/lib is dependent to WAsys_Java_type_util repo for object instancing.
User may either provide its implemented Object_Factory<Poolable_Object> type(recommended way), or simply use the Generic_Object_Factory<Poolable_Object> where instancing the type is not complex.
Any poolable entity/bean must implements Poolable_Object or extend Poolable_Object_Adapter to be considered as a poolable instances.
NOTE: Object state resetting is a user must be done stuff should be considered, since there is no any clue(or automated script/run) to reset a bean before gets acquired and used from an object pool.(considering Poolable_Object.reset_state(void):void method)
This is up to user to either release a pooled object back to the related pool, or not(considering inconsistency). Either ways method release_an_instance(:Poolable_Object):void of related Object_Pool must be called with a usable non-null object, or null to inform pool update its counting state.
HINT: This is recommended to implement java::lang::AutoClosable or extend Poolable_Object_Adapter(which is a Closable), and use the required object inside a try-with_resource(try(){}) to release the Poolable_Object when it's no more required.
Considering following steps need to be done in order to utilize this Object Pool.
0) Defining The Poolable_Object
The type need to be pooled(e.g. Foo_Bar_Entity_Class) should either extend class Poolable_Object_Adapter or implement Poolable_Object.
NOTE: Make sure method reset_state(void):void is correctly implemnted.
public class Foo_Bar_Entity_Class extends Poolable_Object_Adapter{
private int sample_field;
/*called when instance need to be reset*/
@Override public void reset_state() {
/*resetting the object state (ready to be used for next call)*/
sample_field = 0;
}
}Code snippet 0: defining a Poolable_Object
HINT: use WAsys_pojo_http_data_entity_tool which is a simple tool, generate Poolable_Object skeletons in far easier way.
1) Defining The Object_Factory<Poolable_Object>
Provide an Object_Factory<Poolable_Object> (from WAsys_Java_type_util). Could be done using following solutions
- (recommended)Implement interface
Object_Factory<Poolable_Object>and itscreate_object(:Class):Poolable_Object. Instance a non-nullobject, and return.
NOTE: Object pool may not count anynullinstance is provided byObject_Factory.
class Foo_Bar_Entity_Class_Factory implements Object_Factory<Foo_Bar_Entity_Class>{
@Override public Poolable_Object create_object() {
/*create an instance of Foo_Bar_Entity_Class*/
Foo_Bar_Entity_Class _ins = new Foo_Bar_Entity_Class();
/*initialize the instance and return it*/
return _ins;
}
}Code snippet 1: defining a custom Object_Factory<Poolable_Object>
- If the type instancing is done using default public constructor, and is not complex, you also could create a fast
Object_Factoryby instancingGeneric_Object_Factorythen.
Generic_Object_Factory<Foo_Bar_Entity_Class> = new Generic_Object_Factory<Foo_Bar_Entity_Class>(Foo_Bar_Entity_Class.class,...);Code snippet 2: defining a Object_Factory<Poolable_Object> using Generic_Object_Factory
2) Defining The Pool Policy
(optional, but recommended)Prepare an insatnce of Generic_Object_Pool_Policy that fits your requirements about object pooling behavior and state.
3) Creating An Object_Pool Instance
Generic_Object_Pool<E> is the default impl of the Object_Pool<E:Poolable_Object> which is provided by the lib. It has two public static functions(as listed below) to provide concreted Object_Pool<E>
new_pool_instance(:Object_Factory<C>,:Generic_Object_Pool_Policy,arg_thread_safe:bool):Object_Pool<C>(returns a concretedObject_Pool<C>)new_pool_instance(:Class<C>,:Generic_Object_Pool_Policy,arg_thread_safe:bool):Object_Pool<C>(creates anObject_Factory<C>from givenClass<C>and calls teh above func)
//Implement a factory for the type needs to be pooled
class Foo_Bar_Entity_Class_Factory implements Object_Factory<Foo_Bar_Entity_Class_Factory>{
...
}
//creating a thread-safe Object_Pool
Object_Pool<Foo_Bar_Entity_Class_Factory> _pool = Generic_Object_Pool.new_pool_instance(new Foo_Bar_Entity_Class_Factory(),Generic_Object_Pool_Policy.DEF_INS,true/*true(by default) to ask for a thread-safe Object_Pool*/);Code snippet 3: Creating a thread-safe Object_Pool<Foo_Bar_Entity_Class_Factory> with an existing/concreted Object_Factory<Foo_Bar_Entity_Class_Factory>
HINT: since version 0.5.7, the internal pool context(Pool_Context) was removed.
Object_Pool<Foo_Bar_Entity_Class> _pool = new Generic_Object_Pool.new_pool_instance<Foo_Bar_Entity_Class>(Foo_Bar_Entity_Class.class,...);Code snippet 4: creating an Object_Pool<Foo_Bar_Entity_Class_Factory> without an existing Object_Factory
NOTE: Since version 0.5.7, internal context(Pool_Context) was removed, same for Object_Pool_Type_Wrapper<E> as the Object_Pool<:Poolable_Object> is generic now.
Repository is available in maven central repository(and its dependencies). Or you may perform a local build by clone and build it using eitehr maven(recommended) or ant.
Simply add the the following depedency to your pom.xml maven file.
<dependency>
<groupId>com.github.911992</groupId>
<artifactId>WAsys_simple_generic_object_pool</artifactId>
<version>0.5.9</version>
</dependency>Code snippet 5: maven dependency
you may also grab artifact(s) from the central maven repo too.
Clone the repo using git clone https://github.com/911992/WAsys_simple_generic_object_pool.git
And build it using mvn as following
mvn clean dependency:copy-dependencies package
Generated jar(s) will be available under target folder.
Clone the repo using git clone https://github.com/911992/WAsys_simple_generic_object_pool.git
And build it using ant as following
ant clean jar
Generated jar (without dependent artifacts) will be available under dist folder.
Not a maven project? this project is ant compatible too
You may check this repo
Q0: What if user forgets to release an Poolable_Object?
A: Please don't. The Default Generic_Object_Pool implementation may not keep instances of working instances, so for any forgotten releasing objects, there will be no any mem-leak from pool, but inconsistency.
Q1: What if user forgets to implement the reset_state(void):void method on target Poolable_Object type?
A: Please don't. There will be no explicitly-related issue to pool context/object, but this may bring some inconsistency for user business part.
Q2: What if calling for a new objects from an already shutdown Object_Pool?
A: Object_Pool will call the associated factory for object creation, but will not count new creation calls when a pool is in shutdown state.
T0: Object_Pool::get_an_instance(void):Poolable_Object instance, returns a null object
Possible situations:
- This is related to related/given
Object_Factory, make sure the implemented type works well. - Pool is full, and user has initialized/set the
Full_Pool_Object_Creation_Policywith relatedGeneric_Object_Pool_PolicyasReturn_Null.
T1: Thread endlessly wait on Object_Pool::get_an_instance(void):Poolable_Object call
Only debugging could say, but considerring following possible scenarios.
Reason 0: This is probably related to related/given Generic_Object_Pool_Policy, as full_pool_instancing_policy := Wait_Till_One_Free. It means current thread have to waint until anotehr thread release one object, so it could be recycled/reuse for current trhead/call.
Reason 1: Related/given Object_Factory causes the thread lock, make sure it's implemented right.
Also considerign following libs/tools may related to this repo
0. WAsys_Poolable_Object_generator_tool tool to generate Poolable_Object entities
- WAsys_pojo_http_data_entity_tool tool to generate
Fillable_Object(andPoolable_Object) entities
- more control for pooled object at
Object_Poollevel (not sure yet!)