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

Java 我可以增加apache池的超时以减少新对象的创建吗?,java,connection-pooling,pool,Java,Connection Pooling,Pool,我正在尝试将一些对象合并并共享它们,但我注意到线程中存在阻塞。我对Java有点陌生,所以不确定这是我缺乏经验的问题还是池特有的问题。下面是一些复制问题的代码(创建10个线程并共享20个对象,在长循环中执行此操作,以便捕获阻塞)。如果您对其进行分析(Java visualvm或thread视图中的yourkit),您会注意到borrowObject似乎正在阻塞线程。所以问题是,这是正常的行为还是我做错了什么 我可能完全错了,但我在某个地方读到,它可能会在为池创建/删除新对象时阻塞。我只是不明白如何

我正在尝试将一些对象合并并共享它们,但我注意到线程中存在阻塞。我对Java有点陌生,所以不确定这是我缺乏经验的问题还是池特有的问题。下面是一些复制问题的代码(创建10个线程并共享20个对象,在长循环中执行此操作,以便捕获阻塞)。如果您对其进行分析(Java visualvm或thread视图中的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.
*/
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入org.apache.commons.pool.BasePoolableObjectFactory;
导入org.apache.commons.pool.ObjectPool;
导入org.apache.commons.pool.impl.GenericObject池;
公共班机{
公共静态void main(字符串[]a){
ObjectPool fpool=新的GenericObjectPool(新的FooPoolableObjectFactory(),20);
ExecutorService tpool=Executors.newFixedThreadPool(10);
对于(int i=0;i<900000000;++i){
tpool.submit(新食品工人(fpool));
}
}
}
福班{
私有静态int pk=0;
私有整数计数=0;
公共最终int id;
公共食物({
id=pk++;
}
公共整数增量(){
返回++计数;
}
}
类FooWorker实现Runnable{
私有对象池fpool;
公共FooWorker(对象池fpool){
this.fpool=fpool;
}
@凌驾
公开募捐{
Foo-Foo=null;
试一试{
foo=fpool.borrowObject();
//System.out.println(foo.id+:“+foo.increment());
}
捕获(例外e){
e、 printStackTrace();
}
最后{
//这是在finally块中完成的,以确保对象返回到池中
如果(foo!=null){
试一试{
fpool.returnObject(foo);
}
捕获(例外e){
e、 printStackTrace();
}
}
}
}
}
类FooPoolableObjectFactory扩展了BasePoolableObjectFactory{
@凌驾
public Foo makeObject()引发异常{
返回新的Foo();
}
}
/*
示例输出:
1: 1
0: 1
2: 1
3: 1
2: 2
0: 2
2: 3
0: 3
1: 2
3: 2
左边的数字是正在使用的foo对象的id。
右边的数字是foo对象的值。
注意foo是如何被重用的。
*/

不确定“阻塞”线程是什么意思(多个线程在同一个互斥锁上等待?)。apache池实现使用简单的同步,因此,如果您的任务受池中添加和删除对象所需时间的支配,那么它不是最并行的解决方案。假设您在借还电话之间做了一些实际工作,您可能会看到阻塞较少。

这只是一个测试,但是的,我的实际工作非常小,阻塞也同样糟糕。我真正的工作是借用连接上传到消息服务器。还有别的选择吗?或者我可以做一些事情,使阻塞不存在,因为共享的对象彼此不依赖。