java - 我可以增加 apache 池的超时以减少新对象的创建吗?

标签 java connection-pooling pool

我正在尝试汇集一些对象并共享它们,但我注意到线程中发生阻塞。我对 Java 有点陌生,所以不确定这是否是我缺乏经验的问题或特定于池的问题。下面是一些复制该问题的代码(创建 10 个线程并共享 20 个对象,在一个长循环中执行此操作,以便您可以捕获阻塞)。如果您对其进行分析(线程 View 中的Java VisualVM 或yourkit),您会注意到borrowObject 似乎正在阻塞线程。所以问题是,这是正常行为还是我做错了什么?

我可能完全错误,但我在某处读到,当它为池创建/销毁新对象时,它可能会阻塞。我只是不明白如何增加对象的生命周期,以及为什么如果线程不空闲,它甚至需要销毁/生成?

这是一个例子:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apache.commons.pool.BasePoolableObjectFactory;
import org.apache.commons.pool.ObjectPool;
import org.apache.commons.pool.impl.GenericObjectPool;

public class main{
    public static void main(String[] a){
        ObjectPool<Foo> fpool = new GenericObjectPool<Foo>(new FooPoolableObjectFactory(), 20);
        ExecutorService tpool = Executors.newFixedThreadPool(10);

        for(int i = 0; i < 900000000; ++i){
            tpool.submit(new FooWorker(fpool));
        }
    }
}

class Foo{
    private static int pk = 0;
    private int count = 0;
    public final int id;

    public Foo(){
        id = pk++;
    }

    public int increment(){
        return ++count;
    }
}

class FooWorker implements Runnable{
    private ObjectPool<Foo> fpool;

    public FooWorker(ObjectPool<Foo> fpool){
        this.fpool = fpool;
    }

    @Override
    public void run(){
        Foo foo = null;
        try{
            foo = fpool.borrowObject();
            //System.out.println(foo.id + ": " + foo.increment());
        }
        catch(Exception e){
            e.printStackTrace();
        }
        finally{
            // This is done in a finally block to ensure the object is returned to the pool
            if(foo != null){
                try{
                    fpool.returnObject(foo);
                }
                catch(Exception e){
                    e.printStackTrace();
                }
            }
        }
    }
}

class FooPoolableObjectFactory extends BasePoolableObjectFactory<Foo>{

    @Override
    public Foo makeObject() throws Exception{
        return new Foo();
    }
}

/*
Example output:
1: 1
0: 1
2: 1
3: 1
2: 2
0: 2
2: 3
0: 3
1: 2
3: 2

The number on the left is the id of the foo object being used.
The number on the right is the value of the foo object.

Notice how the foos are being reused.
*/

最佳答案

不确定“阻塞”线程是什么意思(多个线程等待同一个互斥体?)。 apache 池实现使用简单的同步,因此如果您的任务主要由从池中添加和删除对象所需的时间控制,那么它不是最并发的解决方案。假设您在借用和返回调用之间做了一些实际工作,您可能会看到更少的阻塞。

关于java - 我可以增加 apache 池的超时以减少新对象的创建吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10450316/

相关文章:

java - 如何使用java分隔数组列表中的对象

mysql池连接与具有相同连接的 Node 获取和释放在每次调用时都会增加

python - Python 中具有多个参数的方法的多重处理

java - 加泰罗尼亚数字生成器的奇怪错误

java - 如何通过负载平衡针对同一数据库运行多个tomcat

java - 如何在 jConsole 本地进程中添加我的应用程序?

mysql - 通过单例的 node.js mySQL 连接

java - C3P0 一台服务器多个数据库

mysql - Nodejs Mysql 库错误 "Too many connections"

用于带代理支持的多线程蜘蛛的 Python 包?