As mentioned in the previous article, a basic idea for improving the performance of Java programs is to reduce frequent object creation and destruction.
Recently I carefully analyzed a program of my own, because this program requires a lot of string operations and will create a large number of temporary stringbuffer objects, which will be discarded once used up. Especially in a function, a stringbuffer is created every time this function is called. This stringbuffer is useless when the function exits, and this function will be called for tens of thousands of times, the accumulated loss of performance can be imagined.
So I thought of using the object pool technology: Every time stringbuffer is used up, it is not destroyed, but stored in it. The next time I use it, I only need to call setlength (0) and I can use it again, low carbon and environmental protection.
As you can see, Apache Commons has a commons-pool (http://commons.apache.org/pool/), a framework for implementing the object pool. So I tried it.
Commons-pool abstracts the object pool as follows:
Public interface objectpool {<br/> Object borrowobject (); <br/> void returnobject (Object borrowed); <br/>}
The term "borrow" and "return" is vivid.
An object in the pool has two states: Active indicates that the object is being used by the program; idle Idle State indicates that the object is idle in the pool and can be allocated.
Therefore, we can easily understand the following configurations:
Maxidle: specifies the maximum number of idle objects. If the idle object exceeds this value, genericobjectpool clears the idle object and reduces it to this value. This is to avoid occupying too many objects in the pool.
Well, let's just talk about the Code:
/** <Br/> * This code is released in the public domain ), you can use it freely <br/> * @ author henix [http://blog.csdn.net/shell_picker] <br/> */</P> <p> Import Org. apache. commons. pool. poolableobjectfactory; <br/> Import Org. apache. commons. pool. impl. genericobjectpool; <br/> Import Org. apache. log4j. logger; </P> <p> public class stringbufferpool {<br/> Private Static logger = logger. getlogger (stringbufferpool. class); </P> <p> private genericobjectpool pool; </P> <p> Private Static stringbufferpool instance = new stringbufferpool (); </P> <p> Public stringbufferpool () {<br/> pool = new genericobjectpool (New stringbufferfactory (); <br/> pool. setmaxactive (-1); <br/> pool. setwhenexhaustedaction (genericobjectpool. when_exhausted_grow); <br/>}</P> <p> Public static stringbufferpool getinstance () {<br/> return instance; <br/>}</P> <p> Public stringbuffer borrowobject () {<br/> stringbuffer ret = NULL; <br/> try {<br/> ret = (stringbuffer) pool. borrowobject (); <br/>}catch (exception e) {<br/> logger. error (E. getmessage (); <br/> If (logger. isdebugenabled () {<br/> E. printstacktrace (); <br/>}< br/> return ret; <br/>}</P> <p> Public void returnobject (stringbuffer OBJ) {<br/> try {<br/> pool. returnobject (OBJ); <br/>} catch (exception e) {<br/> logger. error (E. getmessage (); <br/> If (logger. isdebugenabled () {<br/> E. printstacktrace (); <br/>}</P> <p> class stringbufferfactory implements poolableobjectfactory {</P> <p> Public void activateobject (Object OBJ) throws exception {<br/> (stringbuffer) OBJ ). setlength (0); <br/>}</P> <p> Public void destroyobject (Object OBJ) throws exception {<br/>}</P> <p> Public object makeobject () throws exception {<br/> return New stringbuffer (); <br/>}</P> <p> Public void passivateobject (Object OBJ) throws exception {<br/>}</P> <p> Public Boolean validateobject (Object OBJ) {<br/> return true; <br/>}< br/>}
After understanding the implementation principle of the Object pool, we can also implement one by ourselves. Below is a simple stringbuffer pool implemented by myself:
Hashtable is used to ensure thread security.
/** <Br/> * This code is released in the public domain. You can use it freely <br/> */<br/> Import Java. util. hashtable; <br/> Import Java. util. iterator; </P> <p>/** <br/> * A Simple Object pool for stringbuffer <br/> * @ author henix [http://blog.csdn.net/shell_picker] <br/> */<br/> public class simplebufferpool {<br/> Private Static final object v = new object (); <br/> private hashtable activeobjs; <br/> private hashtable idleobjs; </P> <p> Private Static int maxidle = 8; </P> <p> Private Static simplebufferpool instance = new simplebufferpool (); </P> <p> Public static simplebufferpool getinstance () {<br/> return instance; <br/>}</P> <p> Public simplebufferpool () {<br/> activeobjs = new hashtable (); <br/> idleobjs = new hashtable (); <br/>}</P> <p> Public stringbuffer borrowobject () {<br/> stringbuffer ret; <br/> If (idleobjs. isempty () {<br/> ret = new stringbuffer (); <br/>}else {<br/> synchronized (idleobjs) {<br/> iterator it = idleobjs. keyset (). iterator (); <br/> ret = (stringbuffer) it. next (); <br/> idleobjs. remove (RET); <br/>}< br/> activeobjs. put (Ret, V); <br/> return ret; <br/>}</P> <p> Public void returnobject (stringbuffer SB) {<br/> If (activeobjs. contains (SB) {<br/> activeobjs. remove (SB); <br/> Sb. setlength (0); <br/> idleobjs. put (SB, V); <br/> maintaince (); <br/>}</P> <p> protected synchronized void maintaince () {<br/> int n = idleobjs. size (); <br/> If (n> maxidle) {<br/> iterator it = idleobjs. keyset (). iterator (); <br/> for (INT I = N; I <maxidle; I ++) {<br/> Object key = it. next (); <br/> idleobjs. remove (key); <br/>}< br/>}