ThreadPool学习(初版持续更新)

线程池

线程池状态由32位二,进制组成,前三位为线程池状态后29位为现场数量

private static final int COUNT_BITS = Integer.SIZE - 3;计数位为 32 -3 = 29 现场数量对应

容量
private static final int CAPACITY = (1 << COUNT_BITS) - 1; 意为000111… 29个1

线程池状态正在运行
private static final int RUNNING    = -1 << COUNT_BITS;  -1 左移29位为 111
即将关闭 不接受新任务但是存在的任务继续运行 调用线程池shutdown()方法
private static final int SHUTDOWN   =  0 << COUNT_BITS; 0 左移 29 0
停止 不在处理任务 中断所有任务 调用 shutdownNow()方法
private static final int STOP       =  1 << COUNT_BITS; 1左移29位 001 000... 29个0
当所有的任务已终止,记录的”任务数量”为0,线程池会变为TIDYING状态。当线程池变为TIDYING状态时,会执行钩子函数terminated()。
private static final int TIDYING    =  2 << COUNT_BITS;   -> 010 000... 29个0
当钩子函数terminated()被执行完成之后,线程池彻底终止,就变成TERMINATED状态。
private static final int TERMINATED =  3 << COUNT_BITS; 011 000... 29个0

// Packing and unpacking ctl
与运算计算快
获取当前线程状态
private static int runStateOf(int c)     { return c & ~CAPACITY; }
获取当前线程数量
private static int workerCountOf(int c)  { return c & CAPACITY; }
初始化线程数量调用
private static int ctlOf(int rs, int wc) { return rs | wc; }

主要执行方法
public void execute(Runnable command)

  1. private boolean addWorker(Runnable firstTask, boolean core) {
    //未有结果继续执行
    retry:
    for (;😉 {
    //获取当前线程值
    int c = ctl.get();
    //线程状态
    int rs = runStateOf©;

         // Check if queue empty only if necessary.
         //是否可继续判断,线程是否接受任务
         if (rs >= SHUTDOWN &&
             ! (rs == SHUTDOWN &&
                firstTask == null &&
                ! workQueue.isEmpty()))
             return false;
    
         for (;;) {
         	//线程数量
             int wc = workerCountOf(c);
             //如果数量大于最大数量或者 数量大于核心最大直接结束
             if (wc >= CAPACITY ||
                 wc >= (core ? corePoolSize : maximumPoolSize))
                 return false;
                 //可以直接递增1
             if (compareAndIncrementWorkerCount(c))
                 break retry;
                 //当前线程值
             c = ctl.get();  // Re-read ctl
             //如果这时候线程状态变化重来
             if (runStateOf(c) != rs)
                 continue retry;
             // else CAS failed due to workerCount change; retry inner loop
         }
     }
    
     boolean workerStarted = false;
     boolean workerAdded = false;
     Worker w = null;
     try {
     	//包装我们提交的任务质量交给worker
         w = new Worker(firstTask);
         final Thread t = w.thread;
     	//worker详解
     	将客户的runnabel任务包装到woker里,委托给work执行
     	其中任务可以为空,如为空则去队列中去取,保证线程可持续运用的前提
     	***线程复用的依靠worker中的 while循环一直在寻找任务
    
    
    
         if (t != null) {
             final ReentrantLock mainLock = this.mainLock;
             mainLock.lock();
             try {
                 // Recheck while holding lock.
                 // Back out on ThreadFactory failure or if
                 // shut down before lock acquired.
                 int rs = runStateOf(ctl.get());
    
                 if (rs < SHUTDOWN ||
                     (rs == SHUTDOWN && firstTask == null)) {
                     if (t.isAlive()) // precheck that t is startable
                         throw new IllegalThreadStateException();
                     workers.add(w);
                     int s = workers.size();
                     if (s > largestPoolSize)
                         largestPoolSize = s;
                     workerAdded = true;
                 }
             } finally {
                 mainLock.unlock();
             }
             if (workerAdded) {
                 t.start();
                 workerStarted = true;
             }
         }
     } finally {
         if (! workerStarted)
             addWorkerFailed(w);
     }
     return workerStarted;
    

    }

Worker 实际线程执行者,且循环找任务执行

final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
while (task != null || (task = getTask()) != null) {
w.lock();
// If pool is stopping, ensure thread is interrupted;
// if not, ensure thread is not interrupted. This
// requires a recheck in second case to deal with
// shutdownNow race while clearing interrupt
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
wt.interrupt();
try {
beforeExecute(wt, 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);
}
}
如果核心线程数量满了则加入到阻塞队列中,阻塞队列满了则按最大线程数创建线程执行,如果最大线程数也满了。则执行拒绝策略 线程池默认四种拒绝策略
1.直接由本身线程执行
2.直接拒绝不作为
3.抛出老的任务加入新的任务
4.直接抛出异常

阻塞队列原理

内部存在一个ReentrantLock —
/** Condition for waiting takes */
不是空
private final Condition notEmpty;

不是满
private final Condition notFull;

采用sign 和 await 互相锁定标记唤醒

如加入一个任务 则唤醒非空等待 notEmpty.sign(),
没有则锁定 notEmpty.await()
%%% 注意唤醒等待未知应为while循环处理,否则产生虚假唤醒,导致出现垃圾问题凉凉

ScheduleThreadPool为什么可以周期性执行

    public ScheduledFuture<?> schedule(Runnable command,
                                       long delay,
                                       TimeUnit unit) {
        if (command == null || unit == null)
            throw new NullPointerException();
            //装饰者模式增强callable
        RunnableScheduledFuture<?> t = decorateTask(command,
            new ScheduledFutureTask<Void>(command, null,
                                          triggerTime(delay, unit)));
        delayedExecute(t);
        return t;
    }

ScheduledFutureTask 实际调用对象

        public void run() {
        	//是否为周期对象
            boolean periodic = isPeriodic();
            //如果线程不是运行状态直接取消
            if (!canRunInCurrentRunState(periodic))
                cancel(false);
            else if (!periodic)
            	//非周期对象直接执行
                ScheduledFutureTask.super.run();
            else if (ScheduledFutureTask.super.runAndReset()) {
            	//重新设置触发时间
                setNextRunTime();
                //真正执行
                reExecutePeriodic(outerTask);
            }
        }

此处重新先队列增加task已达到循环调用

    void reExecutePeriodic(RunnableScheduledFuture<?> task) {
        if (canRunInCurrentRunState(true)) {
       	
            super.getQueue().add(task);
            if (!canRunInCurrentRunState(true) && remove(task))
                task.cancel(false);
            else
                ensurePrestart();
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值