前面对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.运行结果