0

これが私のデモです:

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;
}
}

結果.java

public class Result {

private int result;

public Result(){
}

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

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

}

テスト.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();
    }
}
}

次は構成プロパティです。

ここに画像の説明を入力

次は、4 つのスレッドがある場合の Jprofiler のスレッド ビューです。

ここに画像の説明を入力

Test.java が数分間実行された後、いくつかのスレッドがブロックされたままになり、1 つだけがまだ実行されていますが、ログは出力されません。スレッドのことはよくわかりません。誰でも理由を説明できますか?スレッドがブロックされないようにする方法は?

4

2 に答える 2

2

実行サイクルのログを投稿することを検討してください。

スレッドがスリープモードになるまで、スリープは取得したロックを保持するため、Thread.sleep 行にコメントを付けてみましたか。

于 2013-07-17T03:43:43.730 に答える
1

「Thread.sleep(100);」を置き換えてみてください と:

            try {
                synchronized (this) {
                        this.wait(200);
                }
            } catch (InterruptedException e) {
            }
于 2019-11-15T16:08:41.120 に答える