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

}

线程池.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();
    }
}
}

接下来是配置属性:

在此处输入图像描述

接下来是 Jprofiler 的线程视图,当它有 4 个线程时:

在此处输入图像描述

Test.java 运行几分钟后,一些线程一直被阻塞,只有一个仍在运行但不打印任何日志。我不太了解线程的事情。谁能解释为什么?如何避免线程被阻塞?

4

2 回答 2

2

考虑发布执行周期的日志。

您是否尝试评论 Thread.sleep 行,因为 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 回答