commons-pool对象池(2)---实现一个线程池

来源:互联网 发布:看本子专业软件 编辑:程序博客网 时间:2024/05/23 18:03
前面对commons-pool进行了学习,下面着重学习一下利用它实现线程池。

线程池的作用:
       合理利用线程池能够带来三个好处。
       第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
       第二:提高响应速度。当任务到达时,任务可以不需要的等到线程创建就能立即执行。
       第三:提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。但是要做到合理的利用线程池,必须对其原理了如指掌。

还是以例子进行学习:
目录结构:

1.工作线程:可以想象成一个远程连接比如数据库连接等
package commonPool;import org.apache.commons.pool.impl.*;class SimpleThread extends Thread {    private boolean isRunning;    private GenericObjectPool pool ;    public boolean getIsRunning() {        return isRunning;    }    public synchronized void setIsRunning( boolean flag) {        isRunning = flag;        if ( flag) {            this.notify();        }    }    public void setPool( GenericObjectPool pool ) {        this. pool = pool;    }    public SimpleThread() {        isRunning = false;    }    public void destroy() {        System. out.println( "destroy中" );        this.interrupt();    }    public synchronized void run() {        try {            while ( true) {                if (! isRunning) {                    this.wait();                } else {                    System. out.println( this.getName() + "开始处理,处理过程要用5秒" );                    sleep(5000);                    System. out.println( this.getName() + "处理5秒结束,结束处理" );                    setIsRunning( false);                    try {                        pool .returnObject(this );                    } catch (Exception ex) {                        System. out.println( ex);                    }                }            }        } catch (InterruptedException e) {            System. out.println( "我被Interrupted了,所以此线程将被关闭" );            return;        }    }}
2.创建销毁线程池中对象的工厂:
package commonPool;import org.apache.commons.pool.PoolableObjectFactory;public class MyPoolableObjectFactory implements PoolableObjectFactory {    private boolean isDebug = true;    public Object makeObject() throws Exception {        SimpleThread simpleThread = new SimpleThread();        simpleThread.start();        debug( "创建线程:" + simpleThread .getName());        return simpleThread;    }    public void destroyObject(Object obj) throws Exception {        if ( obj instanceof SimpleThread) {            SimpleThread simpleThread = (SimpleThread) obj;            debug( "销毁线程:" + simpleThread .getName());            simpleThread.destroy();        }    }    public boolean validateObject(Object obj) {        return true;    }    public void activateObject(Object obj) throws Exception {    }    public void passivateObject(Object obj) throws Exception {    }    public void setIsDebug( boolean isDebug) {        this. isDebug = isDebug;    }    public boolean getIsDebug() {        return isDebug;    }    private void debug(String debugInfo) {        if ( isDebug) {            System. out.println( debugInfo);        }    }}
3.线程池测试类(兼具线程池管理器的功能):
package commonPool;import org.apache.commons.pool.impl.GenericObjectPool;public class TestThreadPool {    public static void main(String[] args) {        MyPoolableObjectFactory factory = new MyPoolableObjectFactory();        GenericObjectPool pool = new GenericObjectPool( factory);        pool.setMaxActive(20); // 能从池中借出的对象的最大数目        pool.setMaxIdle(20); // 池中可以空闲对象的最大数目        pool.setMaxWait(100); // 对象池空时调用borrowObject方法,最多等待多少毫秒        pool.setTimeBetweenEvictionRunsMillis(600000); // 间隔每过多少毫秒进行一次后台对象清理的行动        pool.setNumTestsPerEvictionRun(-1); // -1表示清理时检查所有线程        pool.setMinEvictableIdleTimeMillis(3000); // 设定在进行后台对象清理时,休眠时间超过了3000毫秒的对象为过期        for ( int i = 0; i < 20; i++) {  //模拟20个客户端请求            try {                SimpleThread simpleThread = (SimpleThread) pool.borrowObject(); //从池子中获取一个线程 ,如果池子为空,先调用工厂的makeObject()创建                simpleThread.setPool( pool);                simpleThread.setIsRunning( true);            } catch (Exception ex) {                System. out.println( ex);            }        }        try {            Thread. sleep(8000); // 休息一会儿,再使用线程池        } catch (InterruptedException ex1) {        }        System. out.println( "--------初次访问线程池要创建,下面模拟第二次访问线程池,不用再创建,直接使用----------------------" );        for ( int i = 0; i < 10; i++) {            try {                SimpleThread simpleThread = (SimpleThread) pool.borrowObject();                simpleThread.setPool( pool);                simpleThread.setIsRunning( true);            } catch (Exception ex) {                System. out.println( ex);            }        }    }}

4.运行结果


原创粉丝点击