线程池与对象池的学习中,个人感觉线程池是将线程转移到内部一直在运行在容器中的线程中来运行,减少的是线程run时间,而不是创建时间,将其引用至新线程,而不需要重新分配资源
1.线程池的类与接口关系构造
Executor-->Executoservice->AbstractExcetorService->ThreadpoolExecutor
Executor->ExecutorService->SchedulEXecutorService+ThreadpoolExceutor->ScheduleThreadpoolExecutor
Executors.new***ThreadPoolExecutor(...)根据不同参数来构造线程池:主要分为5种
newfixThreadPoolExecutor,newSingleThreadExecutor ,newCachedThreadPool以threadpoolexecutor构造完成
newSingleThreadScheduledExecutor,newThreadScheduledExecutor以ScheduleThreadpoolExecutor()构造完成
2.线程池的一些内部源码查看
A.ThreadPoolExecutor()线程池
内 部容器使用blockingQueue,使用Condition配合reentrantlock来监听对象的状态信息,从而实现Queue的消费-生产模 式的构建实现,也保证了线程安全,内部常量使用atomic(基于CAS算法实现原子性操作安全,AMINO框架提供更多类型)或者Static
B.ScheduleThreadPoolExecutor()
是在Threadpoolexecutor基础上实现,主要区别为可以周期内定时执行Runnable任务
内部容器使用DelayedWorkQueue对blockingQueue进行代理使用进行封装,里面使用RunnableScheduledFuture这个接口,能够执行线程,返回future,设置执行时间(可能不准确),使用future模式,Futuretask进行异步结果计算,Callable(Task)类似于thread任务执行单元,但是可以返回参数,实现future模式,所有执行线程的方法均调用schedule(..),
以下是来源于jdk API中一个带方法的类,它设置了 ScheduledExecutorService ,在 1 小时内每 10 秒钟蜂鸣一次:
import static java.util.concurrent.TimeUnit.*; class BeeperControl { private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); public void beepForAnHour() { final Runnable beeper = new Runnable() { public void run() { System.out.println("beep"); } }; final ScheduledFuture<?> beeperHandle = scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS);<!---设置-> scheduler.schedule(new Runnable() { public void run() { beeperHandle.cancel(true); } }, 60 * 60, SECONDS); } 线程安全控制 public int drainTo(Collection<? super Runnable> c) { if (c == null) throw new NullPointerException(); if (c == this) throw new IllegalArgumentException(); final ReentrantLock lock = this.lock;//重入锁 lock.lock(); try { RunnableScheduledFuture first; int n = 0; while ((first = pollExpired()) != null) { c.add(first); ++n; } return n; } finally { lock.unlock(); } } 在ScheduleThreadPoolExecutor.invokeall(Callable()任务列表) 返回future列表代表返回结果集 .submit(Callbale<T>/Runnable)提交一个返回值的任务用于执行,返回一个表示任务的未决结果的 Future。体现使用Callable和future模式的优势 一般执行使用void Execute(Runnable()) 内部周期定时操作的实现: DelayedWorkQueue延时调用比如在poll方法中long timeout, TimeUnit unit,传入时间参数,延时的实现,使用对线程对象的锁机制下关联的 Condition available.awaitNanos(nanos)进行控制.可能不准确,个人整体去看了一遍,但是一步一步实现困难,各种继承和调用关系图实在有点困难,以下是poll()带代码 public RunnableScheduledFuture poll(long timeout, TimeUnit unit) throws InterruptedException { long nanos = unit.toNanos(timeout); final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { for (;;) { RunnableScheduledFuture first = queue[0]; if (first == null) { if (nanos <= 0) return null; else nanos = available.awaitNanos(nanos); } else { long delay = first.getDelay(TimeUnit.NANOSECONDS); if (delay <= 0) return finishPoll(first); if (nanos <= 0) return null; if (nanos < delay || leader != null) nanos = available.awaitNanos(nanos); else { Thread thisThread = Thread.currentThread(); leader = thisThread; try { long timeLeft = available.awaitNanos(delay); nanos -= delay - timeLeft; } finally { if (leader == thisThread) leader = null; } } } } } finally { if (leader == null && queue[0] != null) available.signal(); lock.unlock(); } } 代码均来自于OPEN-JDK中java.lang 和java.util.concurrent包