2012-04-28 36 views
7

Tôi đang cố gắng tạo một nhóm kênh/kết nối với máy chủ xếp hàng và đang cố gắng sử dụng ObjectPool nhưng gặp sự cố khi sử dụng nó từ example trên trang web của họ.Có hướng dẫn hay ví dụ hay về cách sử dụng Java ObjectPool/pools không?

Cho đến nay tôi có chủ đề hoạt động nhưng tôi muốn mỗi người trong số họ lấy một kênh từ hồ bơi và sau đó trả lại. Tôi hiểu làm thế nào để sử dụng nó (vayObject/returnObjects) nhưng không chắc chắn làm thế nào để tạo ra các hồ bơi intial.

Đây là cách các kênh truyền hình được thực hiện trong RabbitMQ:

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

và mã của tôi chỉ sử dụng kênh để làm công cụ. Tôi bối rối vì ví dụ duy nhất tôi có thể tìm thấy (trên trang web của họ) bắt đầu như sau:

private ObjectPool<StringBuffer> pool; 

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

Điều này không có ý nghĩa với tôi. Tôi nhận ra điều này là phổ biến để thiết lập kết nối cơ sở dữ liệu vì vậy tôi đã cố gắng tìm hướng dẫn bằng cách sử dụng cơ sở dữ liệu và ObjectPool nhưng họ dường như sử dụng DBCP cụ thể cho cơ sở dữ liệu (và tôi dường như không thể sử dụng logic cho máy chủ xếp hàng của tôi).

Bất kỳ đề xuất nào về cách sử dụng? Hoặc là có một cách tiếp cận khác được sử dụng cho các hồ bơi trong java?

Trả lời

4

Họ tạo một lớp tạo đối tượng & biết phải làm gì khi chúng được trả lại. Đó có thể là một cái gì đó như thế này dành cho bạn:

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 
} 

bây giờ bạn tạo một ObjectPool<Connection> ở đâu đó:

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

sau đó bạn có thể sử dụng pool bên trong chủ đề của bạn như

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

Các dòng don không có ý nghĩa với bạn là một cách để vượt qua các đối tượng hồ bơi đến một lớp khác nhau. Xem dòng cuối cùng, họ tạo ra các hồ bơi trong khi tạo ra người đọc.

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

wow cảm ơn rất nhiều. Tôi sẽ chơi với mã. Tôi không hiểu nơi để xác định số lượng kênh. Trong ví dụ của bạn là bạn đang chia sẻ một kết nối hoặc có một nơi tôi có thể nói tôi muốn tạo trước các kết nối X? – Lostsoul

+0

Các hồ bơi không được đặt trước đối tượng được gộp chung của chúng. Họ tạo ra chúng theo yêu cầu và đưa chúng từ hồ bơi hoặc tạo ra một cái mới nếu hồ bơi trống. Vì vậy, thường không có giới hạn. Nhưng tôi không biết làm thế nào các lớp học bạn sử dụng hoặc các lớp học bơi làm việc/những gì họ có khả năng. Tôi vừa dịch ví dụ cho bạn :) – zapl

+3

GenericObjectPool sẽ tạo trước các đối tượng gộp chung nếu bạn bật chuỗi gợi ý và đặt thuộc tính "minIdle". http://commons.apache.org/pool/api-1.6/org/apache/commons/pool/impl/GenericObjectPool.html – dnault

3

Bạn sẽ cần triển khai tùy chỉnh PoolableObjectFactory để tạo, xác thực và hủy các đối tượng bạn muốn nhóm. Sau đó vượt qua một thể hiện của nhà máy của bạn để một contructor của ObjectPool và bạn đã sẵn sàng để bắt đầu vay các đối tượng.

Dưới đây là một số mã mẫu. Bạn cũng có thể xem mã nguồn cho commons-dbcp, sử dụng commons-pool.

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

Xin chào, tôi đang cố gắng làm theo ví dụ của bạn và triển khai Tạo nhóm đối tượng. Tôi đang sử dụng commons-pool2-2.1 nhưng nhập khẩu của tôi cho lớp 'BasePoolableObjectFactory' không hoạt động. Ngay cả ví dụ StringBufferFactory đơn giản từ ví dụ [commons] (http://commons.apache.org/proper/commons-pool2/examples.html) không hoạt động. Tuy nhiên, tất cả các hàng nhập khẩu khác liên quan đến pool2 hoạt động tốt. Nó có thể là một cái gì đó siêu đơn giản mà tôi đang thiếu. Bất kỳ đề xuất? – Ellipsis

+0

@Ellipsis Tôi chưa xem xét commons-pool2. Tôi khuyên bạn nên bắt đầu Câu hỏi mới và đăng tất cả các chi tiết về vấn đề của bạn. – dnault

Các vấn đề liên quan