2012-04-28 94 views
7

我想创建一个通道/连接到一个队列服务器的池,并试图使用ObjectPool,但在使用它的网站上的example时遇到了麻烦。有没有关于如何使用Java ObjectPool/pools的好教程或例子?

到目前为止,我有线程可以工作,但我希望他们每个人都能从池中获取一个通道,然后将其返回。我明白如何使用它(borrowObject/returnObjects),但不知道如何创建初始池。

这里的通道是如何在RabbitMQ的制作:

ConnectionFactory factory = new ConnectionFactory(); 
    factory.setHost("localhost"); 
    Connection connection = factory.newConnection(); 
    Channel channel = connection.createChannel(); 

和我的代码只是使用渠道做的东西。我很困惑,因为我能找到(在其网站上)唯一的例子开始像这样:

private ObjectPool<StringBuffer> pool; 

    public ReaderUtil(ObjectPool<StringBuffer> pool) { 
     this.pool = pool; 
    } 

这是没有意义的我。我意识到这是建立数据库连接的常见原因,所以我试图找到使用数据库和ObjectPool的教程,但他们似乎使用特定于数据库的DBCP(并且我似乎无法使用我的队列服务器的逻辑)。

有关如何使用它的任何建议?或者有没有另一种方法用于java中的池?

回答

4

他们创建一个创建对象的类&知道如何返回它们。这可能是这样的你:

public class PoolConnectionFactory extends BasePoolableObjectFactory<Connection> { 

    private final ConnectionFactory factory; 
    public PoolConnectionFactory() { 
     factory = new ConnectionFactory(); 
     factory.setHost("localhost"); 
    } 

    // for makeObject we'll simply return a new Connection 
    public Connection makeObject() { 
     return factory.newConnection(); 
    } 

    // when an object is returned to the pool, 
    // we'll clear it out 
    public void passivateObject(Connection con) { 
     con.I_don't_know_what_to_do(); 
    } 

    // for all other methods, the no-op 
    // implementation in BasePoolableObjectFactory 
    // will suffice 
} 

现在你创建一个ObjectPool<Connection>地方:

ObjectPool<Connection> pool = new StackObjectPool<Connection>(new PoolConnectionFactory()); 

那么你可以使用pool你的线程里面像

Connection c = pool.borrowObject(); 
c.doSomethingWithMe(); 
pool.returnObject(c); 

的线条,唐对你来说没有意义,这是一种将池对象传递给另一个类的方法。看最后一行,他们在创建阅读器时创建了池。

new ReaderUtil(new StackObjectPool<StringBuffer>(new StringBufferFactory())) 
+0

非常感谢。我会玩代码。我不明白在哪里指定频道的数量。在你的例子中你是共享一个连接还是有一个地方我可以说我想要预先创建X连接? – Lostsoul 2012-04-28 23:50:46

+0

池不预先创建他们的池中的对象。他们根据需求创建它们,并将其从游泳池中取出,或者如果游泳池为空,则创建一个新的游泳池。所以通常没有限制。但我不知道你使用的班级或班级班级的工作/他们的能力。我只是为你翻译了这个例子:) – zapl 2012-04-28 23:54:28

+3

如果启用驱逐线程并设置“minIdle”属性,GenericObjectPool将预先创建池化对象。 http://commons.apache.org/pool/api-1.6/org/apache/commons/pool/impl/GenericObjectPool.html – dnault 2012-04-29 00:00:28

3

您需要一个PoolableObjectFactory的自定义实现来创建,验证和销毁想要共享的对象。然后将你的工厂实例传递给ObjectPool的构造器,然后就可以开始借用对象。

下面是一些示例代码。您还可以查看使用commons-pool的commons-dbcp的源代码。

import org.apache.commons.pool.BasePoolableObjectFactory; 
import org.apache.commons.pool.ObjectPool; 
import org.apache.commons.pool.PoolableObjectFactory; 
import org.apache.commons.pool.impl.GenericObjectPool; 

public class PoolExample { 
    public static class MyPooledObject { 
     public MyPooledObject() { 
      System.out.println("hello world"); 
     } 

     public void sing() { 
      System.out.println("mary had a little lamb"); 
     } 

     public void destroy() { 
      System.out.println("goodbye cruel world"); 
     } 
    } 

    public static class MyPoolableObjectFactory extends BasePoolableObjectFactory<MyPooledObject> { 
     @Override 
     public MyPooledObject makeObject() throws Exception { 
      return new MyPooledObject(); 
     } 

     @Override 
     public void destroyObject(MyPooledObject obj) throws Exception { 
      obj.destroy(); 
     } 
     // PoolableObjectFactory has other methods you can override 
     // to valdiate, activate, and passivate objects. 
    } 

    public static void main(String[] args) throws Exception { 
     PoolableObjectFactory<MyPooledObject> factory = new MyPoolableObjectFactory(); 
     ObjectPool<MyPooledObject> pool = new GenericObjectPool<MyPooledObject>(factory); 

     // Other ObjectPool implementations with special behaviors are available; 
     // see the JavaDoc for details 

     try { 
      for (int i = 0; i < 2; i++) { 
       MyPooledObject obj; 

       try { 
        obj = pool.borrowObject(); 
       } catch (Exception e) { 
        // failed to borrow object; you get to decide how to handle this 
        throw e; 
       } 

       try { 
        // use the pooled object 
        obj.sing(); 

       } catch (Exception e) { 
        // this object has failed us -- never use it again! 
        pool.invalidateObject(obj); 
        obj = null; // don't return it to the pool 

        // now handle the exception however you want 

       } finally { 
        if (obj != null) { 
         pool.returnObject(obj); 
        } 
       } 
      } 
     } finally { 
      pool.close(); 
     } 
    } 
} 
+1

嗨,我想跟随你的例子,并实现对象池。我正在使用commons-pool2-2.1,但是我对类'BasePoolableObjectFactory'的导入不起作用。即使从[公地](http://commons.apache.org/proper/commons-pool2/examples.html)例如简单StringBufferFactory示例不起作用。但是,所有其他与pool2相关的导入都可以正常工作。 这可能是超级简单的,我错过了。有什么建议么? – Ellipsis 2014-02-27 02:07:53

+0

@Ellipsis我还没有看过commons-pool2。我会建议开始一个新的问题并发布您的问题的所有细节。 – dnault 2014-02-27 02:48:30

相关问题