是否有关于如何使用 Java ObjectPool/pools 的好的教程或示例?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10368311/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 00:43:10  来源:igfitidea点击:

Are there any good tutorials or examples on how to use Java ObjectPool/pools?

javaconnection-pooling

提问by Lostsoul

I am trying to create a pool of channels/connections to a queue server and was trying to use ObjectPool but am having trouble using it from the exampleon their site.

我正在尝试创建一个到队列服务器的通道/连接池,并尝试使用 ObjectPool,但是在他们网站上的示例中使用它时遇到了问题。

So far I have threads that do work but I want each of them to grab a channel from the pool and then return it. I understand how to use it(borrowObject/returnObjects) but not sure how to create the intial pool.

到目前为止,我有一些可以工作的线程,但我希望每个线程都从池中获取一个通道,然后将其返回。我了解如何使用它(borrowObject/returnObjects)但不确定如何创建初始池。

Here's how channels are made in rabbitmq:

以下是rabbitmq中通道的制作方式:

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

and my code just uses channel to do stuff. I'm confused because the only example I could find (on their site) starts it like this:

我的代码只是使用频道来做事。我很困惑,因为我能找到的唯一例子(在他们的网站上)是这样开始的:

private ObjectPool<StringBuffer> pool;

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

Which does not make sense to me. I realized this is common to establishing database connections so I tried to find tutorials using databases and ObjectPool but they seem to use DBCP which is specific to databases(and I can't seem to use the logic for my queue server).

这对我来说没有意义。我意识到这对于建立数据库连接很常见,所以我试图找到使用数据库和 ObjectPool 的教程,但它们似乎使用特定于数据库的 DBCP(而且我似乎无法使用我的队列服务器的逻辑)。

Any suggestions on how to use it? Or is there a another approach used for pools in java?

关于如何使用它的任何建议?或者是否有另一种用于java中的池的方法?

采纳答案by zapl

They create a class that creates objects & knows what to do when they are returned. That might be something like this for you:

他们创建了一个创建对象的类,并且知道在返回对象时要做什么。这对你来说可能是这样的:

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 
}

now you create a ObjectPool<Connection>somewhere:

现在你创建一个ObjectPool<Connection>地方:

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

then you can use poolinside your threads like

然后你可以pool在你的线程中使用

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

The lines that don't make sense to you are a way to pass the pool object to a different class. See last line, they create the pool while creating the reader.

对您来说没有意义的行是将池对象传递给不同类的一种方式。见最后一行,他们在创建阅读器的同时创建了池。

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

回答by dnault

You'll need a custom implementation of PoolableObjectFactory to create, validate, and destroy the objects you want to pool. Then pass an instance of your factory to an ObjectPool's contructor and you're ready to start borrowing objects.

您将需要 PoolableObjectFactory 的自定义实现来创建、验证和销毁您想要合并的对象。然后将您的工厂实例传递给 ObjectPool 的构造函数,您就可以开始借用对象了。

Here's some sample code. You can also look at the source code for commons-dbcp, which uses commons-pool.

这是一些示例代码。您还可以查看使用 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();
        }
    }
}