首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ObjectPool未按预期重用对象。我如何设计它来汇集资源呢?

ObjectPool未按预期重用对象。我如何设计它来汇集资源呢?
EN

Stack Overflow用户
提问于 2012-05-01 23:45:52
回答 1查看 691关注 0票数 0

对于如何(成功地)将对象返回到池中,我有点困惑。我正在测试为rabbitmq创建一个频道池(这与rabbitmq没有任何特别的关系)。rabbitmq中的过程是创建一个到服务器的连接,然后创建一个通道,我试图让它创建通道并使用池的一部分,但它只是不断创建新的通道,似乎并没有重用旧的通道。我相信是这样的,因为当我检查兔的web用户界面时,它显示我有和我的队列中的项目一样多的频道,但我的上传速度大约是每秒10k条消息,所以我希望只有这个范围内的频道。

我非常确定这会发生,因为我不知道如何成功地返回池。我正在使用returnObject,但是我需要做些什么才能使它准备好被另一个进程使用吗?

下面是代码(它有很多代码,但我认为问题出在MyPooledObject classpool.returnObject(obj)部分:

代码语言:javascript
复制
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;

import java.io.IOException;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.MessageProperties;

public class PoolExample {
    public static class MyPooledObject {
        Connection connection;
        public MyPooledObject() throws IOException {
            System.out.println("hello world");
            ConnectionFactory factory = new ConnectionFactory();
            factory.setHost("localhost");
            connection = factory.newConnection();

        }

        public Channel sing() throws IOException {
            //System.out.println("mary had a little lamb");
            return connection.createChannel();
        }

        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 < 500000000; 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
                    Channel channel = obj.sing();
                    String message = "Mary Had a little lamb";
                    channel.basicPublish( "", "task_queue", 
                            MessageProperties.PERSISTENT_TEXT_PLAIN,
                            message.getBytes());

                } 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();
        }
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-05-02 00:25:09

行为与预期一致。在makeObject上设置一个断点,您会发现您只使用它一次,因为您一次只使用池中的一个对象。

如果您同时使用池中的多个对象,则池将被填满并使用不同的对象。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10400229

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档