1
我想要集合一些對象並共享它們,但我注意到在線程中阻塞。我對Java有點新,所以不確定這是否是我缺乏經驗或特定於池的問題。下面是一些複製問題的代碼(創建10個線程並共享20個對象,在一個長循環中執行此操作,以便捕獲阻塞)。如果你對它進行分析(在線程視圖中使用Java visualvm或yourkit),你會注意到borrowObject似乎阻塞了線程。所以問題是,這是正常的行爲還是我做錯了什麼?我可以增加apache池的超時時間來減少新對象的創建嗎?
我可能是完全錯誤的,但是我在某處讀到它可能會在創建/釋放池的新對象時阻塞。我只是不明白如何增加對象的使用壽命,以及爲什麼它甚至需要在線程不空閒的情況下進行刪除/創建?
下面是一個例子:(?多個線程等待同一個互斥體)
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.
*/
這只是一個測試,但是我的真實工作是非常小的,塊也一樣糟糕。我真正的工作是借用連接來上傳到消息服務器。有其他選擇嗎?或者我可以做的事情,使阻塞不存在,因爲共享的對象不相互依賴。 – Lostsoul