线程池源码阅读(一)

谁说我不能喝 提交于 2020-02-05 04:30:34

线程池源码阅读(一)

仅大致过了下,有问题的请指出,谢谢。

版本

1.8

类关系

在这里插入图片描述

1. Executors

提供创建ThreadPoolExecutor类的快速方法。
建议:不要使用Executors类创建ThreadPoolExecutor

  • newFixedThreadPool
  • newSingleThreadExecutor
  • newCachedThreadPool
  • newScheduledThreadPool
public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>(),
                                  threadFactory);
}


public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>()));
}

public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>(),
                                threadFactory));
}


public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>());
}
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>(),
                                  threadFactory);
}


public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
    return new ScheduledThreadPoolExecutor(corePoolSize);
}

原因一:线程数量无限制

newCachedThreadPoolScheduledThreadPoolExecutor的构造器,最大线程数量为:Integer.MAX_VALUE。若大量任务进来,开辟大量新线程,直至OOM(内存溢出)。

public ScheduledThreadPoolExecutor(int corePoolSize) {
    super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
          new DelayedWorkQueue());
}

原因二:任务队列无边界

newFixedThreadPoolnewSingleThreadExecutor的构造器,使用的阻塞队列为LinkedBlockingQueue,使用的其默认构造器,代码如下:队列容量为Integer.MAX_VALUE。若大量任务进来,存到阻塞无边界队列,直至OOM(内存溢出)。

public LinkedBlockingQueue() {
    this(Integer.MAX_VALUE);
}

2. ThreadFactory

static class DefaultThreadFactory implements ThreadFactory {
    private static final AtomicInteger poolNumber = new AtomicInteger(1);
    private final ThreadGroup group;
    private final AtomicInteger threadNumber = new AtomicInteger(1);
    private final String namePrefix;

    DefaultThreadFactory() {
        SecurityManager s = System.getSecurityManager();
        group = (s != null) ? s.getThreadGroup() :
        Thread.currentThread().getThreadGroup();
        namePrefix = "pool-" +
            poolNumber.getAndIncrement() +
            "-thread-";
    }

    public Thread newThread(Runnable r) {
        Thread t = new Thread(group, r,
                              namePrefix + threadNumber.getAndIncrement(),
                              0);
        if (t.isDaemon())
            t.setDaemon(false);
        if (t.getPriority() != Thread.NORM_PRIORITY)
            t.setPriority(Thread.NORM_PRIORITY);
        return t;
    }
}

3. ExecutorService

1)线程池组件

  1. 线程池管理器:创建、销毁线程池,添加任务
  2. 工作线程:循环执行任务
  3. 任务队列:没有线程用于执行任务时,暂时存放任务
  4. 任务接口:具体任务需实现的接口

2)线程池状态

如何存储线程池状态

private final AtomicInteger ctl

ctl是一个int,32位的原子int类对象,高3位存储线程池状态,低29位存储线程池线程数量。

线程池有哪些状态

状态 描述
running 接受新任务,处理队列任务
shutdown 不接受新任务,处理队列任务
stop 不接受新任务,不处理队列任务,中断正处理的任务
tidying 所有任务终止,线程数为0,线程池转为tidying
terminated terminated()方法已完成

线程池状态切换

running -> shutdown:调用shutdown()finalize()
(running, shutdown) -> stop:调用shutdownNow()
shutdown -> tidying:任务队列和线程池都为空。
stop -> tidying:池为空。
tidying -> terminated:terminated(),一个hook(钩子)方法。

3)方法列表

// 切换池状态为:shutdown。处理正执行任务,不接受新任务
void shutdown();
// 试图中断正执行任务,不处理任务队列的任务,并不接受新任务
List<Runnable> shutdownNow();

// 非运行态,返回true
boolean isShutdown();
// 非运行态,且小于TERMINATED,返回true:SHUTDOWN、STOP、TIDYING
boolean isTerminated();

// 等待:若线程池状态为TERMINATED,返回true;若超时,返回false
boolean awaitTermination(long timeout, TimeUnit unit)

// 提交一个任务
. submit(..);

// 执行所有任务。具体实现见:AbstractExecutorService
<T> T invoke[Xxx](Collection<? extends Callable<T>> tasks);
<T> T invoke[Xxx](Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit);

4. ThreadPoolExecutor

1)属性

// 值为:1110 0000 .. 0000(32位)
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
	
private final ReentrantLock mainLock = new ReentrantLock();
private final Condition termination = mainLock.newCondition();

private final BlockingQueue<Runnable> workQueue;
private final HashSet<Worker> workers = new HashSet<Worker>();
private volatile ThreadFactory threadFactory;

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


private long completedTaskCount;
private volatile long keepAliveTime;
private volatile int corePoolSize;
private volatile int maximumPoolSize;

2)构造器

  1. 核心线程
  2. 最大线程
  3. 临时线程的存活时间
  4. 任务队列
  5. 线程工厂
  6. 拒绝策略

3)拒绝策略

顶层接口

public interface RejectedExecutionHandler {
	void rejectedExecution(Runnable r, ThreadPoolExecutor executor);
}

实现:4

CallerRunsPolicy
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
    if (!e.isShutdown()) {
        r.run();
    }
}	
AbortPolicy:默认
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
    throw new RejectedExecutionException("Task " + r.toString() +
                                         " rejected from " +
                                         e.toString());
}
DiscardPolicy
//不做处理,即丢弃
DiscardOldestPolicy
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
    if (!e.isShutdown()) {
        e.getQueue().poll();
        e.execute(r);
    }
}

4)提交任务策略

1. 线程池运行线程数running < 核心线程数core
	开启新线程
2. running >= core
	提交任务到阻塞队列
		队列未满,提交成功;
		队列已满
			running < max
3. running >= core && 队列已满
	running < max,创建新线程
	running = max,执行拒绝策略
public Future<?> submit(Runnable task) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<Void> ftask = newTaskFor(task, null);
    execute(ftask);
    return ftask;
}

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

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

参考

https://juejin.im/entry/59b232ee6fb9a0248d25139a#threadpoolexecutor``
https://juejin.im/post/5b3cf259e51d45194e0b7204#heading-28
https://blog.csdn.net/u012240455/article/details/81844007

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!