2012-04-28 16 views
7

Próbuję utworzyć pulę kanałów/połączeń z serwerem kolejki i próbowałem użyć ObjectPool, ale mam problemy z używaniem go z poziomu example w ich witrynie.Czy są jakieś dobre samouczki lub przykłady dotyczące korzystania z Java ObjectPool/pools?

Do tej pory mam wątki, które działają, ale chcę, aby każdy z nich pobrał kanał z puli, a następnie go zwrócił. Rozumiem, jak go używać (borrowObject/returnObjects), ale nie wiem, jak utworzyć intial pulę.

Oto jak kanały są wykonane w RabbitMQ:

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

i mój kod prostu wykorzystuje kanał robić rzeczy. Jestem zdezorientowany, ponieważ jedyny przykład, jaki mogłem znaleźć (na ich stronie), rozpoczyna się tak:

private ObjectPool<StringBuffer> pool; 

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

Co nie ma dla mnie sensu. Zdałem sobie sprawę, że jest to powszechne w nawiązywaniu połączeń z bazami danych, więc próbowałem znaleźć samouczki używające baz danych i ObjectPool, ale zdają się używać DBCP, który jest specyficzny dla baz danych (i nie mogę wydawać się używać logiki dla mojego serwera kolejki).

Wszelkie sugestie, jak z niego korzystać? Czy istnieje inne podejście stosowane do puli w java?

Odpowiedz

4

Tworzą klasę, która tworzy obiekty & wie, co zrobić, gdy zostaną zwrócone. To może być coś dla Ciebie:

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 
} 

teraz utworzyć ObjectPool<Connection> gdzieś:

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

następnie można użyć pool wewnątrz swoich wątków jak

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

linie, które don Ma to dla ciebie sens, aby przekazać obiekt puli do innej klasy. Zobacz ostatnią linię, tworzą pulę podczas tworzenia czytnika.

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

wow, dziękuję bardzo. Będę grać z kodem. Nie rozumiem, gdzie określić liczbę kanałów. W twoim przykładzie dzielisz jedno połączenie lub tam, gdzie mogę powiedzieć, że chcę wstępnie utworzyć połączenia X? – Lostsoul

+0

Pule nie mają wstępnego odwzorowania ich połączonego obiektu. Tworzą je na żądanie i zabierają je z puli lub tworzą nowe, jeśli basen jest pusty. Więc zwykle nie ma limitu. Ale nie wiem, w jaki sposób klasy, z których korzystasz, lub klasa basenowa działają/do czego są zdolne. Właśnie przetłumaczyłem dla ciebie przykład :) – zapl

+3

GenericObjectPool wstępnie utworzy połączone obiekty, jeśli włączysz wątek eksmisji i ustawisz właściwość "minIdle". http://commons.apache.org/pool/api-1.6/org/apache/commons/pool/impl/GenericObjectPool.html – dnault

3

Będziesz potrzebować niestandardowej implementacji PoolableObjectFactory do tworzenia, sprawdzania poprawności i niszczenia obiektów, które chcesz połączyć. Następnie przekaż instancję swojej fabryki do konstruktora ObjectPool i możesz zacząć pożyczać obiekty.

Oto przykładowy kod. Możesz również spojrzeć na kod źródłowy dla commons-dbcp, który używa wspólnej puli.

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

Witam, próbuję wykonać twój przykład i zaimplementować pulowanie obiektów. Używam commons-pool2-2.1, ale mój import dla klasy 'BasePoolableObjectFactory' nie działa. Nawet prosty przykład StringBufferFactory z przykładu [commons] (http://commons.apache.org/proper/commons-pool2/examples.html) nie działa. Jednak wszystkie inne przywozy związane z pulą 2 działają dobrze. To chyba coś bardzo prostego, czego mi brakuje. Jakieś sugestie? – Ellipsis

+0

@ Ellipsis Jeszcze nie obejrzałem commons-pool2. Zaleciłbym rozpoczęcie nowego pytania i opublikowanie wszystkich szczegółów twojego problemu. – dnault

Powiązane problemy