pool(一)——入门

 这一系列主要说的是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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CachePool线程池是一种基于缓存机制的线程池,可以提高线程的处理效率和速度。下面是一个自定义的CachePool线程池实现: ```java import java.util.concurrent.*; public class CachePool { private ExecutorService executorService; public CachePool() { int corePoolSize = 0; int maximumPoolSize = Integer.MAX_VALUE; long keepAliveTime = 60L; TimeUnit unit = TimeUnit.SECONDS; BlockingQueue<Runnable> workQueue = new SynchronousQueue<Runnable>(); ThreadFactory threadFactory = Executors.defaultThreadFactory(); RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy(); executorService = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler); } public void execute(Runnable task) { executorService.execute(task); } public void shutdown() { executorService.shutdown(); } public boolean isTerminated() { return executorService.isTerminated(); } } ``` 该线程池使用了ThreadPoolExecutor类来实现,其中corePoolSize和maximumPoolSize都设置为最大值Integer.MAX_VALUE,因此线程池中的线程数不会有限制。keepAliveTime设置为60秒,表示线程在空闲60秒后会被回收。workQueue采用了SynchronousQueue,这是一个没有容量限制的阻塞队列,可以让任务立即提交给线程处理,从而避免了任务的排队等待。RejectedExecutionHandler采用了ThreadPoolExecutor.AbortPolicy,表示如果线程池已经达到最大容量,且所有线程都在执行任务,此时再有新任务提交时,会抛出RejectedExecutionException异常,从而避免了线程池过载的情况。execute方法用于提交任务,shutdown方法用于关闭线程池,isTerminated方法用于判断线程池是否已经关闭。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值