pool(一)——入门

来源:互联网 发布:淘宝扣分12分会怎么样 编辑:程序博客网 时间:2024/04/30 15:27

这一系列主要说的是org.apache.commons.pool2包提供的ObjectPool以及对应的实现源码。

1.已有连接池举例

目前已知的对象池的应用,比如:

数据库连接池——org.apache.commons.dbcp2的BasicDataSource

jedis连接池——redis.clients.jedis的JedisPool。

2.线程池

线程池的用法和这个不太一样,因为线程的run方法执行完之后,一个线程的使命就结束了。所以如果要想重用线程,就需要阻止run方法的结束,用死循环等方法。目前jdk线程池使用的是结合LinkedBlockingQueue,通过队列的阻塞方法让当前线程休眠,等待任务并处理,实现单个线程的重用。

execute方法会添加一个worker。

public void execute(Runnable command) {    if (workerCountOf(c) < corePoolSize) {        if (addWorker(command, true))    ...}
private boolean addWorker(Runnable firstTask, boolean core) {        ...        Worker w = new Worker(firstTask);        Thread t = w.thread;        ...        try {            ...            workers.add(w);            ...        } finally {            mainLock.unlock();        }        t.start();        ...}
用当前的Runnable task构造一个Worker,并启动该worker中的thread,该thread以该Woker自己为任务,任务内容是

/** Delegates main run loop to outer runWorker  */        public void run() {            runWorker(this);        }
final void runWorker(Worker w) {        Runnable task = w.firstTask;        w.firstTask = null;        boolean completedAbruptly = true;        try {            while (task != null || (task = getTask()) != null) {                w.lock();                clearInterruptsForTaskRun();                try {                    beforeExecute(w.thread, task);                    Throwable thrown = null;                    try {                        task.run();                    } catch (RuntimeException x) {                        thrown = x; throw x;                    } catch (Error x) {                        thrown = x; throw x;                    } catch (Throwable x) {                        thrown = x; throw new Error(x);                    } finally {                        afterExecute(task, thrown);                    }                } finally {                    task = null;                    w.completedTasks++;                    w.unlock();                }            }            completedAbruptly = false;        } finally {            processWorkerExit(w, completedAbruptly);        }    }
while循环第一次执行的时候task不是null,执行一次之后,task为null,getTask从队列中取任务。

取任务的时候,如果allowCoreThreadTimeOut是true,或者当前线程数量已经超过了核心线程数量,从LinkedBlockingQueue中取任务会有等待时间,等待的时间由keepAliveTime决定。

关于线程池详细部分在线程池篇再说,这里只是说一下为什么线程的重用不能使用对象池。





0 0
原创粉丝点击