2012-04-28 105 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

相關問題