• ThreadPoolExecutor


    private final BlockingQueue<Runnable> workQueue; //任务缓存队列,用来保存等待中的任务,等待worker线程空闲时执行任务 
    private final ReentrantLock mainLock = new ReentrantLock(); //更新 poolSize, corePoolSize,maximumPoolSize, runState, and workers set 时需要持有这个锁 
    private final HashSet<Worker> workers = new HashSet<Worker>(); //用来保存工作中的执行线程 
    private volatile long keepAliveTime; //超过corePoolSize外的线程空闲存活之间 如果池中当前有多个线程核心数,则在等待这段时间而不处理任务后,将终止多余的线程
    private volatile boolean allowCoreThreadTimeOut; //是否对corePoolSize内的线程设置空闲存活时间 
    private volatile int corePoolSize; //核心线程数 
    private volatile int maximumPoolSize; //最大线程数(即线程池中的线程数目大于这个参数时,提交的任务会被放进任务缓存队列) 
    private volatile int poolSize; //线程池中的当前线程数 
    private volatile RejectedExecutionHandler handler; //任务拒绝策略 当提交任务数超过maxmumPoolSize+workQueue之和时,任务会交给RejectedExecutionHandler来处理
    private volatile ThreadFactory threadFactory; //线程工厂,用来新建线程 
    private int largestPoolSize; //记录线程池中出现过的最大线程数大小 
    private long completedTaskCount; //已经执行完的线程数
    TimeUnit: keepAliveTime时间单位
     
    1.当线程池小于corePoolSize时,新提交任务将创建一个新线程执行任务,即使此时线程池中存在空闲线程。 
    2.当线程池达到corePoolSize时,新提交任务将被放入workQueue中,等待线程池中任务调度执行 
    3.当workQueue已满,且maximumPoolSize>corePoolSize时,新提交任务会创建新线程执行任务 
    4.当提交任务数超过maximumPoolSize时,新提交任务由RejectedExecutionHandler处理 
    5.当线程池中超过corePoolSize线程,空闲时间达到keepAliveTime时,关闭空闲线程 
    6.当设置allowCoreThreadTimeOut(true)时,线程池中corePoolSize线程空闲时间达到keepAliveTime也将关闭 
     
    下面都假设任务队列没有大小限制:
     
    如果线程数量<=核心线程数量,那么直接启动一个核心线程来执行任务,不会放入队列中。
    如果线程数量>核心线程数,但<=最大线程数,并且任务队列是LinkedBlockingDeque的时候,超过核心线程数量的任务会放在任务队列中排队。
    如果线程数量>核心线程数,但<=最大线程数,并且任务队列是SynchronousQueue的时候,线程池会创建新线程执行任务,这些任务也不会被放在任务队列中。这些线程属于非核心线程,在任务完成后,闲置时间达到了超时时间就会被清除。
    如果线程数量>核心线程数,并且>最大线程数,当任务队列是LinkedBlockingDeque,会将超过核心线程的任务放在任务队列中排队。也就是当任务队列是LinkedBlockingDeque并且没有大小限制时,线程池的最大线程数设置是无效的,他的线程数最多不会超过核心线程数。
    如果线程数量>核心线程数,并且>最大线程数,当任务队列是SynchronousQueue的时候,会因为线程池拒绝添加任务而抛出异常。
    任务队列大小有限时
     
    当LinkedBlockingDeque塞满时,新增的任务会直接创建新线程来执行,当创建的线程数量超过最大线程数量时会抛异常。
    SynchronousQueue没有数量限制。因为他根本不保持这些任务,而是直接交给线程池去执行。当任务数量超过最大线程数时会直接抛异常。
     
    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();
            //如果线程池停止,确保线程被中断;
            //如果没有,确保线程没有中断。这
            //第二种情况需要重新检查处理
            //在清除中断时,立即关闭race
            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);
        }
    }
     
  • 相关阅读:
    jq ajax注册检查用户名
    jq ajax页面交互
    Digit Counting UVA – 1225
    Molar mass UVA – 1586
    P1571 眼红的Medusa
    A. Digits Sequence Dividing
    Codeforces Round #535 (Div. 3) a题
    Digit Generator UVA – 1583
    Good Bye 2018 B
    电梯 HDU – 1008
  • 原文地址:https://www.cnblogs.com/gqymy/p/10303365.html
Copyright © 2020-2023  润新知