深入浅出java并发编程(线程池)

前言

参考链接

1.ThreadPoolExecutor继承关系

继承关系

2. Executor 接口

executor是一个顶层接口。

2.1 Executor 源码

public interface Executor {
    void execute(Runnable command);
}

Executor 接口只有一个核心方法 execute() ,参数为Runnable接口,没有返回值。

2.2 Runnable 源码

@FunctionalInterface
public interface Runnable {
    public abstract void run();
}

2.3 ThreadPoolExecutor的execute实现

 public void execute(Runnable command) {
 		//参数校验      
        if (command == null)
            throw new NullPointerException();  
                
        int c = ctl.get();
        //比较核心线程数	
        if (workerCountOf(c) < corePoolSize) {        
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        //
        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();
            
            if (! isRunning(recheck) && remove(command))
                reject(command);
                
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        //如果添加失败则拒绝
        else if (!addWorker(command, false))
            reject(command);
    }

2.3.1 execute方法相关属性

    private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
    private static final int COUNT_BITS = Integer.SIZE - 3;
    private static final int CAPACITY   = (1 << COUNT_BITS) - 1;

    // runState is stored in the high-order bits
    private static final int RUNNING    = -1 << COUNT_BITS;
    private static final int SHUTDOWN   =  0 << COUNT_BITS;
    private static final int STOP       =  1 << COUNT_BITS;
    private static final int TIDYING    =  2 << COUNT_BITS;
    private static final int TERMINATED =  3 << COUNT_BITS;

    // 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;
    }

2.3.2 addWorker方法

private boolean addWorker(Runnable firstTask, boolean core) {
        retry:
        for (;;) {
            int c = ctl.get();
            int rs = runStateOf(c);

            // 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;
                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 {
            w = new Worker(firstTask);
            final Thread t = w.thread;
            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;
    }

3. ExecutorService

3.1 结构如下

ExecutorService

3.2源码如下

public interface ExecutorService extends Executor {
   //关闭
    void shutdown();
    //停止所有正在执行的任务
    List<Runnable> shutdownNow();  
    //判断是否关闭
    boolean isShutdown();
    //如果关闭后所有任务都已完成,则为 true
    boolean isTerminated();  
    //阻塞直到所有任务在关闭请求后完成执行
    boolean awaitTermination(long timeout, TimeUnit unit)
        throws InterruptedException;
        
    <T> Future<T> submit(Callable<T> task);
    
    <T> Future<T> submit(Runnable task, T result);
     
    Future<?> submit(Runnable task);

    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
        throws InterruptedException;
 
    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
                                  long timeout, TimeUnit unit)
        throws InterruptedException; 
 
    <T> T invokeAny(Collection<? extends Callable<T>> tasks)
        throws InterruptedException, ExecutionException;
   
    <T> T invokeAny(Collection<? extends Callable<T>> tasks,
                    long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

3.3 submit方法

使用RunnableFuture封装扩展了execute方法接收Callable类型参数。
在这里插入图片描述

3.4 关闭线程池

在这里插入图片描述
在这里插入图片描述
调用shutdown方法之后,线程池将不再接口新任务,内部会将所有已提交的任务处理完毕,处理完毕之后,工作线程自动退出。

而调用shutdownNow方法后,线程池会将还未处理的(在队里等待处理的任务)任务移除,将正在处理中的处理完毕之后,工作线程自动退出。

3.5 判断

isShutdown和isTerminated继承ExecutorService,isTerminating是线程池原生方法,搜索调用发现源码中没有方法调用它。

3.5.1 isShutdown和 isTerminated

在这里插入图片描述

3.5.2 awaitTermination

在这里插入图片描述

3.6 invoke 调用

批量处理任务,Any和All的区别是有一个任务返回和全部任务返回结果。

    public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
        throws InterruptedException, ExecutionException {
        try {
            return doInvokeAny(tasks, false, 0);
        } catch (TimeoutException cannotHappen) {
            assert false;
            return null;
        }
    }

    public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
                           long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException {
        return doInvokeAny(tasks, true, unit.toNanos(timeout));
    }

    public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
        throws InterruptedException {
        //
        if (tasks == null)
            throw new NullPointerException();
        //
        ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
        //
        boolean done = false;
        //
        try {
            for (Callable<T> t : tasks) {
                RunnableFuture<T> f = newTaskFor(t);
                futures.add(f);
                execute(f);
            }
            for (int i = 0, size = futures.size(); i < size; i++) {
                Future<T> f = futures.get(i);
                if (!f.isDone()) {
                    try {
                        f.get();
                    } catch (CancellationException ignore) {
                    } catch (ExecutionException ignore) {
                    }
                }
            }
            done = true;
            return futures;
        } finally {
            if (!done)
                for (int i = 0, size = futures.size(); i < size; i++)
                    futures.get(i).cancel(true);
        }
    }

    public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
                                         long timeout, TimeUnit unit)
        throws InterruptedException {
        if (tasks == null)
            throw new NullPointerException();
        long nanos = unit.toNanos(timeout);
        ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
        boolean done = false;
        try {
            for (Callable<T> t : tasks)
                futures.add(newTaskFor(t));

            final long deadline = System.nanoTime() + nanos;
            final int size = futures.size();

            // Interleave time checks and calls to execute in case
            // executor doesn't have any/much parallelism.
            for (int i = 0; i < size; i++) {
                execute((Runnable)futures.get(i));
                nanos = deadline - System.nanoTime();
                if (nanos <= 0L)
                    return futures;
            }

            for (int i = 0; i < size; i++) {
                Future<T> f = futures.get(i);
                if (!f.isDone()) {
                    if (nanos <= 0L)
                        return futures;
                    try {
                        f.get(nanos, TimeUnit.NANOSECONDS);
                    } catch (CancellationException ignore) {
                    } catch (ExecutionException ignore) {
                    } catch (TimeoutException toe) {
                        return futures;
                    }
                    nanos = deadline - System.nanoTime();
                }
            }
            done = true;
            return futures;
        } finally {
            if (!done)
                for (int i = 0, size = futures.size(); i < size; i++)
                    futures.get(i).cancel(true);
        }
    }

4. AbstractExecutorService

提供 ExecutorService 部分方法的默认实现和其他需求的扩充。

4.1 结构图如下

结构图

4.2 类中方法

4.2.1 submit方法

submit相关实现如下

在这里插入图片描述
RunnableFuture接口在这里插入图片描述

4.2.2 doInvokeAny方法

invokeAny 方法实现的主要逻辑封装

private <T> T doInvokeAny(Collection<? extends Callable<T>> tasks,
                              boolean timed, long nanos)
        throws InterruptedException, ExecutionException, TimeoutException {
        if (tasks == null)
            throw new NullPointerException();
        int ntasks = tasks.size();
        if (ntasks == 0)
            throw new IllegalArgumentException();
        ArrayList<Future<T>> futures = new ArrayList<Future<T>>(ntasks);
        ExecutorCompletionService<T> ecs =
            new ExecutorCompletionService<T>(this);
            
        try {
            // Record exceptions so that if we fail to obtain any
            // result, we can throw the last exception we got.
            ExecutionException ee = null;
            final long deadline = timed ? System.nanoTime() + nanos : 0L;
            Iterator<? extends Callable<T>> it = tasks.iterator();

            // Start one task for sure; the rest incrementally
            futures.add(ecs.submit(it.next()));
            --ntasks;
            int active = 1;

            for (;;) {
                Future<T> f = ecs.poll();
                if (f == null) {
                    if (ntasks > 0) {
                        --ntasks;
                        futures.add(ecs.submit(it.next()));
                        ++active;
                    }
                    else if (active == 0)
                        break;
                    else if (timed) {
                        f = ecs.poll(nanos, TimeUnit.NANOSECONDS);
                        if (f == null)
                            throw new TimeoutException();
                        nanos = deadline - System.nanoTime();
                    }
                    else
                        f = ecs.take();
                }
                if (f != null) {
                    --active;
                    try {
                        return f.get();
                    } catch (ExecutionException eex) {
                        ee = eex;
                    } catch (RuntimeException rex) {
                        ee = new ExecutionException(rex);
                    }
                }
            }

            if (ee == null)
                ee = new ExecutionException();
            throw ee;

        } finally {
            for (int i = 0, size = futures.size(); i < size; i++)
                futures.get(i).cancel(true);
        }
    }

4.2.3 newTaskFor方法

将Runnable和Callable封装为RunnableFuture类型返回。
在这里插入图片描述

5 ThreadPoolExecutor的内部类

5.1 Worker

private final class Worker
        extends AbstractQueuedSynchronizer
        implements Runnable
    {
      
        private static final long serialVersionUID = 6138294804551838833L;

        /** Thread this worker is running in.  Null if factory fails. */
        final Thread thread;
        /** Initial task to run.  Possibly null. */
        Runnable firstTask;
        /** Per-thread task counter */
        volatile long completedTasks;

        /**
         * Creates with given first task and thread from ThreadFactory.
         * @param firstTask the first task (null if none)
         */
        Worker(Runnable firstTask) {
            setState(-1); // inhibit interrupts until runWorker
            this.firstTask = firstTask;
            this.thread = getThreadFactory().newThread(this);
        }

        /** Delegates main run loop to outer runWorker  */
        public void run() {
            runWorker(this);
        }

        // Lock methods
        //
        // The value 0 represents the unlocked state.
        // The value 1 represents the locked state.

        protected boolean isHeldExclusively() {
            return getState() != 0;
        }

        protected boolean tryAcquire(int unused) {
            if (compareAndSetState(0, 1)) {
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }
            return false;
        }

        protected boolean tryRelease(int unused) {
            setExclusiveOwnerThread(null);
            setState(0);
            return true;
        }

        public void lock()        { acquire(1); }
        public boolean tryLock()  { return tryAcquire(1); }
        public void unlock()      { release(1); }
        public boolean isLocked() { return isHeldExclusively(); }

        void interruptIfStarted() {
            Thread t;
            if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
                try {
                    t.interrupt();
                } catch (SecurityException ignore) {
                }
            }
        }
    }

5.2 策略内部类

5.2.1 AbortPolicy

直接抛出异常 RejectedExecutionException
在这里插入图片描述

5.2.2 CallerRunsPolicy

线程池关闭丢弃任务,没有关闭交给当前线程执行任务。
在这里插入图片描述

5.2.3 DiscardOldestPolicy

线程池关闭直接丢弃,线程池没有关闭获取队列并移除头部元素,执行任务。
在这里插入图片描述

5.2.4 DiscardPolicy

什么都不做,相当于丢弃任务r。
在这里插入图片描述

6. ThreadPoolExecutor的属性

6.1 结构图

属性结构图

6.2 源码如下

    private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
    private static final int COUNT_BITS = Integer.SIZE - 3;
    private static final int CAPACITY   = (1 << COUNT_BITS) - 1;

    // runState is stored in the high-order bits
    private static final int RUNNING    = -1 << COUNT_BITS;
    private static final int SHUTDOWN   =  0 << COUNT_BITS;
    private static final int STOP       =  1 << COUNT_BITS;
    private static final int TIDYING    =  2 << COUNT_BITS;
    private static final int TERMINATED =  3 << COUNT_BITS;
    
    private final BlockingQueue<Runnable> workQueue;
    
    private final ReentrantLock mainLock = new ReentrantLock();

    private final HashSet<Worker> workers = new HashSet<Worker>();
   
    private final Condition termination = mainLock.newCondition();

    private int largestPoolSize;

    private long completedTaskCount;

    private volatile ThreadFactory threadFactory;

    private volatile RejectedExecutionHandler handler;

 
    private volatile long keepAliveTime;


    private volatile boolean allowCoreThreadTimeOut;

    private volatile int corePoolSize;

    private volatile int maximumPoolSize;
 
    private static final RejectedExecutionHandler defaultHandler =
        new AbortPolicy();

    private static final RuntimePermission shutdownPerm =
        new RuntimePermission("modifyThread");
   
    private final AccessControlContext acc;
    
    private static final boolean ONLY_ONE = true;

6.3 属性解析

7.ThreadPoolExecutor 构造函数

构造函数

7.1 五个参数构造函数

使用默认线程工厂和默认处理策略。

 public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }

7.2 默认策略构造函数

使用了默认的handler

  public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             threadFactory, defaultHandler);
    }

在这里插入图片描述
在这里插入图片描述

7.3 默认线程工厂构造函数

六个参数的构造函数,使用了默认的线程工厂Executors.defaultThreadFactory()

 public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              RejectedExecutionHandler handler) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), handler);
    }

7.4 完全参数构造函数

 public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
       //参数校验 四个部分                                                     
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
       //参数校验 三部分 队列 工厂 处理    
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
       //acc赋值
        this.acc = System.getSecurityManager() == null ?
                null :
                AccessController.getContext();
       //其他参数赋值
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

acc参数的使用

在这里插入图片描述
在这里插入图片描述在这里插入图片描述
acc参数一共出现了四次,其中第一次是定义,第二次是构造函数赋值,其余出现在finalize方法中
在这里插入图片描述
不过finalize方法并没有被其他方法调用,所以acc的用处还未知。

7.5 合理地配置线程池

7.5.1 cpu密集

CPU密集型任务应该尽可能小的线程,如配置cpu数量+1个线程的线程池。

7.5.2 io密集

由于IO密集型任务并不是一直在执行任务,不能让cpu闲着,则应配置尽可能多的线程,如:cup数量*2。

7.5.3 队列

使用队列的时候建议使用有界队列,有界队列增加了系统的稳定性,如果采用无界队列,任务太多的时候可能导致系统OOM,直接让系统宕机。

8. ThreadPoolExecutor 方法

8.1 public方法

8.1.1 allowCoreThreadTimeOut

在这里插入图片描述

8.1.2 allowsCoreThreadTimeOut

在这里插入图片描述
调用发生在setKeepAliveTime方法
**加粗样式**

8.1.3 getKeepAliveTime

本类中无调用
在这里插入图片描述

8.1.4 prestartAllCoreThreads

本类无调用
在这里插入图片描述

8.1.5 prestartCoreThread

在这里插入图片描述

8.1.6 purge

未发现该方法调用
在这里插入图片描述

8.1.7 remove

移除任务,执行tryTerminate()方法。方法调用发生在execute方法
在这里插入图片描述
在这里插入图片描述

8.1.8 setKeepAliveTime

本类无调用
在这里插入图片描述

8.2 protected方法

8.2.1 afterExecute

任务执行之后调用的方法
在这里插入图片描述

8.2.2 beforeExecute

任务执行之前调用的方法
在这里插入图片描述

8.2.3 terminated

在这里插入图片描述
tryTerminate 方法中的调用
在这里插入图片描述

8.3 无修饰符方法

8.3.1 ensurePrestart

本类无调用
在这里插入图片描述

8.3.2 isRunningOrShutdown

本类无调用
在这里插入图片描述

8.3.3 onShutdown

在这里插入图片描述
调用位置shutdown方法
在这里插入图片描述

8.3.4 reject

拒绝任务,调用发生在execute方法中,
在这里插入图片描述
在这里插入图片描述

8.3.5 runWorker

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);
        }
    }

调用发生在内部类Worke中
在这里插入图片描述

8.3.6 tryTerminate

final void tryTerminate() {
        for (;;) {
            int c = ctl.get();
            if (isRunning(c) ||
                runStateAtLeast(c, TIDYING) ||
                (runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
                return;
            if (workerCountOf(c) != 0) { // Eligible to terminate
                interruptIdleWorkers(ONLY_ONE);
                return;
            }

            final ReentrantLock mainLock = this.mainLock;
            mainLock.lock();
            try {
                if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
                    try {
                        terminated();
                    } finally {
                        ctl.set(ctlOf(TERMINATED, 0));
                        termination.signalAll();
                    }
                    return;
                }
            } finally {
                mainLock.unlock();
            }
            // else retry on failed CAS
        }
    }

调用位置
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

8.4 private方法

8.4.1 addWorker

private boolean addWorker(Runnable firstTask, boolean core) {
        retry:
        for (;;) {
            int c = ctl.get();
            int rs = runStateOf(c);

            // 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;
                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 {
            w = new Worker(firstTask);
            final Thread t = w.thread;
            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;
    }

8.4.2 addWorkerFailed

在这里插入图片描述
调用发生在 addWorker
在这里插入图片描述

8.4.3 advanceRunState

在这里插入图片描述
调用关系
在这里插入图片描述
在这里插入图片描述

8.4.4 checkShutdownAccess

在这里插入图片描述
调用关系 shutdown和shutdownnow方法

8.4.5 compareAndDecrementWorkerCount

在这里插入图片描述

8.4.6 compareAndIncrementWorkerCount

在这里插入图片描述

8.4.7 ctlOf

private static int ctlOf(int rs, int wc) { return rs | wc; }

8.4.8 decrementWorkerCount

在这里插入图片描述

8.4.9 drainQueue

在这里插入图片描述

8.4.10 interruptIdleWorkers

在这里插入图片描述

8.4.11 interruptIdleWorkers

在这里插入图片描述

8.4.12 interruptWorkers

在这里插入图片描述

8.4.13 isRunning

在这里插入图片描述

8.4.14 processWorkerExit

在这里插入图片描述

8.4.15 runStateAtLeast

在这里插入图片描述

8.4.16 runStateLessThan

在这里插入图片描述

8.4.16 runStateOf

    private static int workerCountOf(int c) {
        return c & ~CAPACITY;
    }

8.4.17 workerCountOf

    private static int workerCountOf(int c) {
        return c & CAPACITY;
    }

9 常见问题

9.1 submit和execute方法有什么区别

void execute(Runnable command);

submit方法

  1. 区别1 来源接口不同,execute来源Executor接口,而submit来源ExecutorService接口。
  2. 区别2 返回值不同 execute返回void,而submit返回Future对象。
  3. 区别3 入参不同 execute接收Runnable接口,submit还支持Callable接口。
  4. 区别4 异常抛出 execute当前线程遇到异常直接抛出,而submit在主线程调用get方法时才会抛出ExecutionException异常。
    在这里插入图片描述
    FutureTask 中get方法如图所示
    在这里插入图片描述
    FutureTask 中report方法如图所示
    在这里插入图片描述

9.2 newFixedThreadPool

在这里插入图片描述
在这里插入图片描述
创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变,在提交新任务,任务将会进入等待队列中等待。如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。内部使用了无限容量的LinkedBlockingQueue阻塞队列来缓存任务,任务如果比较多,如果处理不过来,会导致队列堆满,引发OOM。

9.3 newCachedThreadPool

在这里插入图片描述
创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程,

那么就会回收部分空闲(60秒处于等待任务到来)的线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。此线程池的最大值是Integer的最大值(2^31-1)。内部使用了SynchronousQueue同步队列来缓存任务,此队列的特性是放入任务时必须要有对应的线程获取任务,任务才可以放入成功。如果处理的任务比较耗时,任务来的速度也比较快,会创建太多的线程引发OOM。

9.4 newSingleThreadExecutor

在这里插入图片描述
创建一个单线程的线程池。这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。内部使用了无限容量的LinkedBlockingQueue阻塞队列来缓存任务,任务如果比较多,单线程如果处理不过来,会导致队列堆满,引发OOM。

9.5 线程池中队列的使用

//定义存放Runnable类型队列
private final BlockingQueue<Runnable> workQueue;
//判断是否为空
workQueue.isEmpty()
//
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
Runnable r = timed ? workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) : workQueue.take();
//类同 add 不过不会抛异常
workQueue.offer(command)
//获取队列大小
workQueue.size()
//移出元素
workQueue.remove(task)

9.6 异步线程执行失败怎么办

问题描述:如何保证主线程和异步线程的原子性,即不允许一个失败一个成功。
以一个主线程和一个子线程为例,有两种特殊情况,主失败和子失败。
类比分布式事务。

9.7 为什么先添加队列后创建线程

最大线程数其实是为了应付突发状况。举个装修的例子,正常情况下施工队只要 3 个人去干活,这 3 人其实就是核心线程,但是由于工头接的活太多了,导致 3 个人在约定工期内干不完,所以工头又去找了 2 个人来一起干,所以 3 是核心线程数,5 是最大线程数。平时就是 3 个人干活,特别忙的时候就找 5 个,等闲下来就会把多余的 2 个辞了。

名词简称

corePoolSize 核心池大小
maximumPoolSize 最大池大小
keepAliveTime 存活时间
workQueue 队列
threadFactory 工厂
handler 处理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值