Java并发

线程状态
NEW
RUNNABLE
RUNNING
BLOCKED
DEAD

线程池相关
ThreadPoolExecutor
execute(Runnable command)

  1. If fewer than corePoolSize threads are running, try to start a new thread with the given command as its first task. The call to addWorker atomically checks runState and workerCount, and so prevents false alarms that would add threads when it shouldn't, by returning false.
  2. If a task can be successfully queued, then we still need to double-check whether we should have added a thread (because existing ones died since last checking) or that the pool shut down since entry into this method. So we recheck state and if necessary roll back the enqueuing if stopped, or start a new thread if there are none.
  3. If we cannot queue task, then we try to add a new thread. If it fails, we know we are shut down or saturated and so reject the task.
  4. 如果运行的线程少于corePoolSize,则尝试将给定的命令作为其第一个任务启动一个新线程。对addWorker的调用会自动检查runState和workerCount,从而通过返回false来防止误报,因为误报会在不应该添加线程的时候添加线程。
  5. 如果一个任务可以成功排队,那么我们仍然需要再次检查是否应该添加一个线程(因为现有的线程在上次检查之后已经死亡),或者池在进入这个方法之后已经关闭。因此,我们将重新检查状态,并在必要时在停止队列时回滚队列,或者在没有队列时启动一个新线程。
    3.如果我们不能对任务进行排队,那么我们将尝试添加一个新线程。如果它失败了,我们知道我们已经关闭或饱和了,所以拒绝任务。

Worker内部函数
runWorker(Worker w)
主工作器运行循环。重复地从队列中获取任务并执行它们,同时处理以下几个问题:1。我们可以从一个初始任务开始,在这种情况下,我们不需要得到第一个任务。否则,只要pool在运行,我们就从getTask获得任务。如果返回null,则由于池状态或配置参数的改变,worker退出。其他退出是由外部代码中的异常抛出导致的,在这种情况下completedsudden会保持,这通常会导致processWorkerExit替换该线程。2. 在运行任何任务之前,需要获取锁,以防止在任务执行时发生其他池中断,然后我们确保,除非池停止,否则这个线程没有自己的中断集。3.每个任务运行之前都有一个beforeExecute调用,它可能会抛出一个异常,在这种情况下,我们导致线程死亡(completedtrue中断循环),而不处理该任务。4. 假设beforeExecute正常完成,我们运行任务,收集其抛出的任何异常发送给afterExecute。我们分别处理RuntimeException、Error(规范保证我们会捕获这两种情况)和任意Throwables。因为我们不能在Runnable.run中重新抛出Throwables,所以我们在输出(到线程的UncaughtExceptionHandler)时将其包装在Errors中。任何抛出的异常也会保守地导致线程死亡。5. 在task.run完成后,调用afterExecute,它也会抛出一个异常,也会导致线程死亡。根据JLS Sec 14.20,即使task.run抛出异常,这个异常也会生效。异常机制的净效果是,afterExecute和线程的UncaughtExceptionHandler拥有我们所能提供的关于用户代码遇到的任何问题的准确信息。

Worker就是线程池中的每个在执行的线程,通过执行完上一个后,去workQueue中获取下一个去执行,继承AbstractQueuedSynchronizer
private final class Worker
extends AbstractQueuedSynchronizer
implements Runnable
Class Worker主要维护正在运行任务的线程的中断控制状态,以及其他次要的簿记工作。这个类机会性地扩展了AbstractQueuedSynchronizer,以简化获取和释放围绕每个任务执行的锁。这可以防止那些旨在唤醒等待任务的工作线程而不是中断正在运行的任务的中断。我们实现了一个简单的不可重入互斥锁,而不是使用ReentrantLock,因为我们不想让工作任务在调用池控制方法(如setCorePoolSize)时能够重新获得锁。此外,为了在线程真正开始运行任务之前抑制中断,我们将锁状态初始化为负值,并在启动时将其清除(在runWorker中)。

Executors类 工厂方法

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

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

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


ReentrantLock 中静态内部类 Sync 基于 AbstractQueuedSynchronizer。Sync的子类 FairSync,NonfairSync。
FairSync的tryAcquire()调用了AbstractQueuedSynchronizer的函数hasQueuedPredecessors,判断队列中是否为空。
AbstractQueuedSynchronizer调用LockSupport,LockSupport调用sun.misc.Unsafe。
BlockingQueue基于ReentrantLock

ThreadLocal
Entry WeakReference
ThreadLocal基于静态内部类ThreadLocalMap,ThreadLocalMap是Thread对象的成员变量,其中的Entry继承WeakReference,溢出前GC之后会回收,但是如果有get逻辑,那就是还有强引用连接,所以不回收。

posted @ 2022-02-03 22:16  Yu\.W  阅读(38)  评论(0编辑  收藏  举报