2012-04-28 2 views
7

Я пытаюсь создать пул каналов/подключений к серверу очереди и пытался использовать ObjectPool, но у меня проблемы с его использованием из example на их сайте.Есть ли хорошие учебники или примеры использования Java ObjectPool/pool?

До сих пор у меня есть потоки, которые работают, но я хочу, чтобы каждый из них захватил канал из пула, а затем вернул его. Я понимаю, как его использовать (loanObject/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

wow Большое спасибо. Я буду играть с кодом. Я не понимаю, где указать количество каналов. В вашем примере вы делитесь одним соединением или там, где я могу сказать, что хочу предварительно создать 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. Затем передайте экземпляр вашей фабрики в contructor ObjectPool, и вы готовы начать заимствование объектов.

Вот пример кода. Вы также можете посмотреть исходный код для 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' не работает. Даже простой пример StringBufferFactory из примера [commons] (http://commons.apache.org/proper/commons-pool2/examples.html) не работает. Тем не менее, все остальные импортные товары, связанные с пулом 2, отлично работают. Это, наверное, нечто простое, что мне не хватает. Какие-либо предложения? – Ellipsis

+0

@ Эллипсис Я еще не смотрел на общедоступный бассейн2. Я бы рекомендовал начать новый Вопрос и опубликовать все детали вашей проблемы. – dnault

Смежные вопросы