2013-07-17 113 views
0

這裏是我的演示:爲什麼線程在我使用Apache-Commons-Pool時被阻塞?

PoolableObjectFactoryImpl.java

public class PoolableObjectFactoryImpl implements PoolableObjectFactory<Result> { 

private static Logger logger = Logger.getLogger("BackgroundLog"); 

@Override 
public void activateObject(Result obj) throws Exception { 
    logger.info("==activate result.=="); 
    obj.setResult(-999); 
} 

@Override 
public void destroyObject(Result obj) throws Exception { 
    logger.info("==destroy result.=="); 
    obj = null; 
} 

@Override 
public Result makeObject() throws Exception { 
    logger.info("==make result.=="); 
    Result result = new Result(); 
    return result; 
} 

@Override 
public void passivateObject(Result obj) throws Exception { 
    logger.info("==passivate result.=="); 
    obj.setResult(-999); 
} 

@Override 
public boolean validateObject(Result obj) { 
    /*if(obj.getResult() == -999){ 
     logger.info("==validate result true.=="); 
     return true; 
    }else{ 
     logger.info("==validate result false.=="); 
     return false; 
    }*/ 
    logger.info("==validate result true.=="); 
    return true; 
} 

} 

ThreadPool.java

public class ThreadPool extends GenericObjectPool { 

private static Logger logger = Logger.getLogger("BackgroundLog"); 

private static ThreadPool pool = null; 

private Map<String, String> map = getConfig(); 


private ThreadPool() { 

    this.setFactory(new PoolableObjectFactoryImpl()); 

    this.setMaxActive(Integer.parseInt(map.get("maxActive"))); 

    this.setWhenExhaustedAction(Byte.valueOf(map.get("whenExhaustedAction"))); 

    this.setMaxWait(Long.parseLong(map.get("maxWait"))); 

    this.setMaxIdle(Integer.parseInt(map.get("maxIdle"))); 

    this.setTestOnBorrow(Boolean.valueOf(map.get("testOnBorrow"))); 

    this.setTestOnReturn(Boolean.valueOf(map.get("testOnReturn"))); 
    this.setTimeBetweenEvictionRunsMillis(Long.parseLong(map.get("timeBetweenEvictionRunsMillis"))); 

    this.setNumTestsPerEvictionRun(Integer.parseInt(map.get("numTestsPerEvictionRun"))); 
    this.setMinEvictableIdleTimeMillis(Long.parseLong(map.get("minEvictableIdleTimeMillis"))); 

    this.setTestWhileIdle(Boolean.valueOf(map.get("testWhileIdle"))); 


} 


public static ThreadPool getInstance() { 
    if (pool == null) { 
     synchronized (ThreadPool.class) { 
      if (pool == null) { 
       logger.info("thread pool is initialized."); 
       pool = new ThreadPool(); 
      } 
     } 
    } 
    return pool; 
} 

/** 
* 
* <p>Title: getConfig</p> 
* <p>Description: get pool configuration</p> 
* @return 
*/ 
public Map<String, String> getConfig() { 
    Map<String, String> map = new HashMap<String, String>(); 
    Properties props = new Properties(); 
    try { 
     InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("pool.properties"); 
     props.load(in); 
     Enumeration en = props.propertyNames(); 
     while (en.hasMoreElements()) { 
      String key = (String) en.nextElement(); 
      map.put(key, props.getProperty(key)); 
     } 
     in.close(); 
    } catch (Throwable t) { 
     logger.error(t.getMessage(), t); 
    } 
    return map; 
} 
} 

Result.java

public class Result { 

private int result; 

public Result(){ 
} 

public int getResult(){ 
    return this.result; 
} 

public void setResult(int result){ 
    this.result = result; 
} 

} 

Test.java

public class Test implements Runnable { 

private static Logger logger = Logger.getLogger("BackgroundLog"); 

private String name = null; 

public Test(String name){ 
    this.name = name; 
} 

public String getName(){ 
    return this.name; 
} 

public void setName(String name){ 
    this.name = name; 
} 

@Override 
public void run() { 
    ThreadPool pool = ThreadPool.getInstance(); 
    for(int i=0;i<1000;i++){ 
     try { 
       Result result = (Result)pool.borrowObject(); 
       logger.info("numActive: "+ pool.getNumActive()+"\t"+"numIdle: "+pool.getNumIdle()); 
       logger.info("thread "+getName()+" "+i+" borrow object from pool "+result.getResult()+"."); 
       result.setResult(0); 
       pool.returnObject(result); 
       logger.info("return object to pool."); 
       Thread.sleep(100); 
     } catch (Exception e) { 
      logger.info("thread "+getName()+" "+i); 
      e.printStackTrace(); 
     } 
    } 
} 

public static void main(String[] args) { 
    for(int i=0;i<50;i++){ 
     Thread t = new Thread(new Test("t"+i)); 
     t.start(); 
    } 
} 
} 

接下來是配置屬性:

enter image description here

接下來是線程的JProfiler查看當它有4個線程:

enter image description here

Test.java運行幾分鐘後,一些線程繼續被屏蔽,只有一個線程仍在運行,但不打印任何日誌。我不太瞭解線程。 任何人都可以解釋爲什麼?如何避免線程被阻塞?

回答

1

考慮發佈執行週期的日誌。

您是否嘗試評論Thread.sleep行,因爲睡眠將保持其獲取的鎖定直到線程處於睡眠模式。

相關問題