Design Pattern—-04.Creational.Object Pool.Pattern (Java Sample)

來源:互聯網
上載者:User
Intent
  • Object pooling can offer a significant performance boost; it is most effective in situations where the cost of initializing a class instance is high, the rate of instantiation of a class is high, and the number of instantiations in use at any one time is low.
Problem
  • Object pools (otherwise known as resource pools) are used to manage the object caching. A client with access to a Object pool can avoid creating a new Objects by simply asking the pool for one that has already been instantiated instead. Generally the pool will be a growing pool, i.e. the pool itself will create new objects if the pool is empty, or we can have a pool, which restricts the number of objects created.
  • It is desirable to keep all Reusable objects that are not currently in use in the same object pool so that they can be managed by one coherent policy. To achieve this, the Reusable Pool class is designed to be a singleton class.
Discussion
  • The Object Pool lets others “check out” objects from its pool, when those objects are no longer needed by their processes, they are returned to the pool in order to be reused.
  • However, we don’t want a process to have to wait for a particular object to be released, so the Object Pool also instantiates new objects as they are required, but must also implement a facility to clean up unused objects periodically.
Structure

The general idea for the Connection Pool pattern is that if instances of a class can be reused, you avoid creating instances of the class by reusing them.

  • <strong>Reusable</strong> - Instances of classes in this role collaborate with other objects for a limited amount of time, then they are no longer needed for that collaboration.
  • <strong>Client</strong> - Instances of classes in this role use Reusable objects.
  • <strong>ReusablePool</strong> - Instances of classes in this role manage Reusable objects for use by Client objects.

Usually, it is desirable to keep all Reusable objects that are not currently in use in the same object pool so that they can be managed by one coherent policy. To achieve this, the ReusablePool class is designed to be a singleton class. Its constructor(s) are private, which forces other classes to call its getInstance method to get the one instance of the ReusablePool class.

A Client object calls a ReusablePool object’s acquireReusable method when it needs a Reusable object. A ReusablePool object maintains a collection of Reusable objects. It uses the collection of Reusable objects to contain a pool of Reusable objects that are not currently in use.

If there are any Reusable objects in the pool when the acquireReusable method is called, it removes a Reusable object from the pool and returns it. If the pool is empty, then the acquireReusable method creates a Reusable object if it can. If the acquireReusable method cannot create a new Reusable object, then it waits until a Reusable object is returned to the collection.

Client objects pass a Reusable object to a ReusablePool object’s releaseReusable method when they are finished with the object. The releaseReusable method returns a Reusable object to the pool of Reusable objects that are not in use.

In many applications of the Object Pool pattern, there are reasons for limiting the total number of Reusable objects that may exist. In such cases, the ReusablePool object that creates Reusable objects is responsible for not creating more than a specified maximum number of Reusable objects. If ReusablePool objects are responsible for limiting the number of objects they will create, then the ReusablePool class will have a method for specifying the maximum number of objects to be created. That method is indicated in the above diagram as setMaxPoolSize.

Example

Do you like bowling? If you do, you probably know that you should change your shoes when you getting the bowling club. Shoe shelf is wonderful example of Object Pool. Once you want to play, you’ll get your pair (aquireReusable) from it. After the game, you’ll return shoes back to the shelf (releaseReusable).

Check list
  1. Create ObjectPool class with private array of Objects inside
  2. Create acquare and release methods in ObjectPool class
  3. Make sure that your ObjectPool is Singleton
Rules of thumb
  • The Factory Method pattern can be used to encapsulate the creation logic for objects. However, it does not manage them after their creation, the object pool pattern keeps track of the objects it creates.
  • Object Pools are usually implemented as Singletons.
Java Sample
// ObjectPool Class
public abstract class ObjectPool<T> {  private long expirationTime;  private Hashtable<T, Long> locked, unlocked;  public ObjectPool() {    expirationTime = 30000; // 30 seconds    locked = new Hashtable<T, Long>();    unlocked = new Hashtable<T, Long>();  }  protected abstract T create();  public abstract boolean validate(T o);  public abstract void expire(T o);  public synchronized T checkOut() {    long now = System.currentTimeMillis();    T t;    if (unlocked.size() > 0) {      Enumeration<T> e = unlocked.keys();      while (e.hasMoreElements()) {        t = e.nextElement();        if ((now - unlocked.get(t)) > expirationTime) {          // object has expired          unlocked.remove(t);          expire(t);          t = null;        } else {          if (validate(t)) {            unlocked.remove(t);            locked.put(t, now);            return (t);          } else {            // object failed validation            unlocked.remove(t);            expire(t);            t = null;          }        }      }    }    // no objects available, create a new one    t = create();    locked.put(t, now);    return (t);  }  public synchronized void checkIn(T t) {    locked.remove(t);    unlocked.put(t, System.currentTimeMillis());  }}//The three remaining methods are abstract //and therefore must be implemented by the subclasspublic class JDBCConnectionPool extends ObjectPool<Connection> {  private String dsn, usr, pwd;  public JDBCConnectionPool(String driver, String dsn, String usr, String pwd) {    super();    try {      Class.forName(driver).newInstance();    } catch (Exception e) {      e.printStackTrace();    }    this.dsn = dsn;    this.usr = usr;    this.pwd = pwd;  }  @Override  protected Connection create() {    try {      return (DriverManager.getConnection(dsn, usr, pwd));    } catch (SQLException e) {      e.printStackTrace();      return (null);    }  }  @Override  public void expire(Connection o) {    try {      ((Connection) o).close();    } catch (SQLException e) {      e.printStackTrace();    }  }  @Override  public boolean validate(Connection o) {    try {      return (!((Connection) o).isClosed());    } catch (SQLException e) {      e.printStackTrace();      return (false);    }  }}

JDBCConnectionPool will allow the application to borrow and return database connections:

public class Main {  public static void main(String args[]) {    // Do something...    ...    // Create the ConnectionPool:    JDBCConnectionPool pool = new JDBCConnectionPool(      "org.hsqldb.jdbcDriver", "jdbc:hsqldb://localhost/mydb",      "sa", "secret");    // Get a connection:    Connection con = pool.checkOut();    // Use the connection    ...    // Return the connection:    pool.checkIn(con);   }}
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.