2012-04-28 5 views
7

キューサーバーへのチャネル/接続のプールを作成しようとしましたが、ObjectPoolを使用しようとしましたが、サイト上でexampleから問題を使用しています。Java ObjectPool/poolの使い方に関する良いチュートリアルや例はありますか?

これまではスレッドが動作していましたが、各スレッドがプールからチャネルを取得して戻すようにしています。私はそれを使用する方法(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()); 

、あなたはそのドンラインが

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

のようなあなたのスレッド内poolを使用することができますがプールオブジェクトを別のクラスに渡す方法は理にかなっています。最後の行を参照し、リーダーを作成しながらプールを作成します。

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

大変ありがとうございます。私はコードで遊ぶだろう。私はどこのチャンネルを指定するのか分からない。あなたの例では、1つの接続を共有しているか、X接続を事前に作成したいと言うことができる場所がありますか? – Lostsoul

+0

プールはプールされたオブジェクトを事前作成しません。彼らは必要に応じてそれらを作成し、プールからそれらを取るか、またはプールが空の場合は新しいものを作成します。したがって、通常は制限はありません。しかし、あなたが使っているクラスやプールクラスがどのように働いているのか/彼らができることは分かりません。私はちょうどあなたのための例を翻訳しました:) – zapl

+3

GenericObjectPoolは、退去スレッドを有効にして "minIdle"プロパティを設定すると、プールされたオブジェクトをあらかじめ作成します。 http://commons.apache.org/pool/api-1.6/org/apache/commons/pool/impl/GenericObjectPool.html – dnault

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'のインポートは機能しません。 [commons](http://commons.apache.org/proper/commons-pool2/examples.html)の単純なStringBufferFactoryの例でさえ、動作しません。しかし、pool2に関連する他のすべてのインポートは正常に動作します。 これはおそらく私が紛失している非常に単純なものです。助言がありますか? – Ellipsis

+0

@Ellipsis私はまだコモンズプール2を見ていない。私は新しい質問を開始し、あなたの問題のすべての詳細を投稿することをお勧めします。 – dnault

関連する問題