美文网首页
多线程浅析之一:基本概念

多线程浅析之一:基本概念

作者: 无为无悔 | 来源:发表于2022-04-05 15:51 被阅读0次

    一、线程池的属性

    先来看一下线程池的构造方法,总结就是7大属性,这里Doug Lea写的很清楚了,下面简要翻译一下加深印象

        /**
         * Creates a new {@code ThreadPoolExecutor} with the given initial
         * parameters.
         *
         * @param corePoolSize the number of threads to keep in the pool, even
         *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
         * @param maximumPoolSize the maximum number of threads to allow in the
         *        pool
         * @param keepAliveTime when the number of threads is greater than
         *        the core, this is the maximum time that excess idle threads
         *        will wait for new tasks before terminating.
         * @param unit the time unit for the {@code keepAliveTime} argument
         * @param workQueue the queue to use for holding tasks before they are
         *        executed.  This queue will hold only the {@code Runnable}
         *        tasks submitted by the {@code execute} method.
         * @param threadFactory the factory to use when the executor
         *        creates a new thread
         * @param handler the handler to use when execution is blocked
         *        because the thread bounds and queue capacities are reached
         * @throws IllegalArgumentException if one of the following holds:<br>
         *         {@code corePoolSize < 0}<br>
         *         {@code keepAliveTime < 0}<br>
         *         {@code maximumPoolSize <= 0}<br>
         *         {@code maximumPoolSize < corePoolSize}
         * @throws NullPointerException if {@code workQueue}
         *         or {@code threadFactory} or {@code handler} is null
         */
        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();
            this.corePoolSize = corePoolSize;
            this.maximumPoolSize = maximumPoolSize;
            this.workQueue = workQueue;
            this.keepAliveTime = unit.toNanos(keepAliveTime);
            this.threadFactory = threadFactory;
            this.handler = handler;
        }
    

    以下属性都是volatile关键字修饰,好处是基于内存屏障避免编译器指令重排造成变量取值不准,同时保证发生更改后的主存立即写入主存,保证其他线程从内存而不是本身私有的栈空间读取准确值

    1. corePoolSize:the number of threads to keep in the pool, even if they are idle, unless {@code allowCoreThreadTimeOut} is set (核心线程数:不管它们创建以后是不是空闲的。线程池需要保持 corePoolSize 数量的线程,除非设置了 allowCoreThreadTimeOut,注意这个数字允许为0。)

    2. maximumPoolSize:the maximum number of threads to allow in the pool。(最大线程数:线程池中最多允许创建 maximumPoolSize 个线程,注意必须大于0,并且需保证maximumPoolSize >= corePoolSize。)

    3. keepAliveTime:when the number of threads is greater than the core, this is the maximum time that excess idle threads will wait for new tasks before terminating。(存活时间:根据unit而定,最终转换为单位nanoseconds(纳秒,千分之一微秒),如果经过 keepAliveTime 时间后,超过核心线程数的线程还没有接受到新的任务,那就回收,注意这里没说核心工作线程什么时候回收。)

    4. unit:the time unit for the {@code keepAliveTime} argument (keepAliveTime 的时间单位,不能为负,TimeUnit类定义在J.U.C,里面多处有用到。)

    5. workQueue:the queue to use for holding tasks before they are executed. This queue will hold only the {@code Runnable} tasks submitted by the {@code execute} method。(存放等待执行任务的队列:当提交的任务数超过核心线程数大小后,再提交的任务就存放在这里。它仅仅用来存放被 execute 方法提交的 Runnable 任务。)

    6. threadFactory:the factory to use when the executor creates a new thread。(线程工程:用来创建线程工厂。比如这里面可以自定义线程名称,当进行虚拟机栈分析时,看着名字就知道这个线程是哪里来的,不会懵逼。)

    7. handler :the handler to use when execution is blocked because the thread bounds and queue capacities are reached。(拒绝策略:当队列里面放满了任务、最大线程数的线程都在工作时,这时继续提交的任务线程池就处理不了,应该执行怎么样的拒绝策略。)

    二、线程池的状态

         /**
         * The runState provides the main lifecycle control, taking on values:
         *
         *   RUNNING:  Accept new tasks and process queued tasks
         *   SHUTDOWN: Don't accept new tasks, but process queued tasks
         *   STOP:     Don't accept new tasks, don't process queued tasks,
         *             and interrupt in-progress tasks
         *   TIDYING:  All tasks have terminated, workerCount is zero,
         *             the thread transitioning to state TIDYING
         *             will run the terminated() hook method
         *   TERMINATED: terminated() has completed
         *
         * The numerical order among these values matters, to allow
         * ordered comparisons. The runState monotonically increases over
         * time, but need not hit each state. The transitions are:
         *
         * RUNNING -> SHUTDOWN
         *    On invocation of shutdown(), perhaps implicitly in finalize()
         * (RUNNING or SHUTDOWN) -> STOP
         *    On invocation of shutdownNow()
         * SHUTDOWN -> TIDYING
         *    When both queue and pool are empty
         * STOP -> TIDYING
         *    When pool is empty
         * TIDYING -> TERMINATED
         *    When the terminated() hook method has completed
         */
    
    1. RUNNING
    • 状态说明:线程池处在RUNNING状态时,能够接收新任务,以及对已添加的任务进行处理。
    • 状态切换:线程池的初始化状态是RUNNING。换句话说,线程池被一旦被创建,就处于RUNNING状态,并且线程池中的任务数为0!
    1. SHUTDOWN
    • 状态说明:线程池处在SHUTDOWN状态时,不接收新任务,但能处理已添加的任务。
    • 状态切换:调用线程池的shutdown()接口时,线程池由RUNNING -> SHUTDOWN。
    1. STOP
    • 状态说明:线程池处在STOP状态时,不接收新任务,不处理已添加的任务,并且会中断正在处理的任务。
    • 状态切换:调用线程池的shutdownNow()接口时,线程池由(RUNNING or SHUTDOWN ) -> STOP。
    1. TIDYING
    • 状态说明:当所有的任务已终止,ctl记录的”任务数量”为0,线程池会变为TIDYING状态。当线程池变为TIDYING状态时,会执行钩子函数terminated()。terminated()在ThreadPoolExecutor类中是空的,若用户想在线程池变为TIDYING时,进行相应的处理,可以通过重载terminated()函数来实现。
    • 状态切换:当线程池在SHUTDOWN状态下,阻塞队列为空并且线程池中执行的任务也为空时,就会由 SHUTDOWN -> TIDYING。
      当线程池在STOP状态下,线程池中执行的任务为空时,就会由STOP -> TIDYING。
    1. TERMINATED
    • 状态说明:线程池彻底终止,就变成TERMINATED状态。
    • 状态切换:线程池处在TIDYING状态时,执行完terminated()之后,就会由 TIDYING -> TERMINATED。

    三、线程的状态

    public enum State {
            /**
             * Thread state for a thread which has not yet started.
             */
            NEW,
    
            /**
             * Thread state for a runnable thread.  A thread in the runnable
             * state is executing in the Java virtual machine but it may
             * be waiting for other resources from the operating system
             * such as processor.
             */
            RUNNABLE,
    
            /**
             * Thread state for a thread blocked waiting for a monitor lock.
             * A thread in the blocked state is waiting for a monitor lock
             * to enter a synchronized block/method or
             * reenter a synchronized block/method after calling
             * {@link Object#wait() Object.wait}.
             */
            BLOCKED,
    
            /**
             * Thread state for a waiting thread.
             * A thread is in the waiting state due to calling one of the
             * following methods:
             * <ul>
             *   <li>{@link Object#wait() Object.wait} with no timeout</li>
             *   <li>{@link #join() Thread.join} with no timeout</li>
             *   <li>{@link LockSupport#park() LockSupport.park}</li>
             * </ul>
             *
             * <p>A thread in the waiting state is waiting for another thread to
             * perform a particular action.
             *
             * For example, a thread that has called <tt>Object.wait()</tt>
             * on an object is waiting for another thread to call
             * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
             * that object. A thread that has called <tt>Thread.join()</tt>
             * is waiting for a specified thread to terminate.
             */
            WAITING,
    
            /**
             * Thread state for a waiting thread with a specified waiting time.
             * A thread is in the timed waiting state due to calling one of
             * the following methods with a specified positive waiting time:
             * <ul>
             *   <li>{@link #sleep Thread.sleep}</li>
             *   <li>{@link Object#wait(long) Object.wait} with timeout</li>
             *   <li>{@link #join(long) Thread.join} with timeout</li>
             *   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
             *   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
             * </ul>
             */
            TIMED_WAITING,
    
            /**
             * Thread state for a terminated thread.
             * The thread has completed execution.
             */
            TERMINATED;
        }
    
    1. NEW
    • 状态说明:创建后未执行
    • 状态切换:未调用start()方法
    1. RUNNABLE
    • 状态说明:JVM运行状态,实际是处于运行,或处于就绪(例如等待CPU时间片)
    • 状态切换:调用start()方法,或yield()进入就绪,NEW -> RUNABLE <-> BLOCKED
    1. BLOCKED
    • 状态说明:请求monitor lock进入synchronized方法或者程序块,未请求到锁,从而被阻塞
    • 状态切换:RUNABLE <-> BLOCKED
    1. WAITING
    • 状态说明:主动挂起等待,看作是无限期
    • 状态切换:Object.wait() ,Thread.join() ,LockSupport.park() 进入等待,Object.notify() / Object.notifyAll(),其他线程执行完,LockSupport.unpark(Thread) 解除等待,RUNABLE <-> WAITING
    1. TIMED_WAITING
    • 状态说明:有限期等待
    • 状态切换:Thread.sleep() 或调用上面WAITING里面的方法带上超时时间参数,RUNABLE <-> TIMED_WAITING
    1. TERMINATED
    • 状态说明:终止
    • 状态切换:run()或主线程执行完毕,RUNABLE -> TERMINATED

    相关文章

      网友评论

          本文标题:多线程浅析之一:基本概念

          本文链接:https://www.haomeiwen.com/subject/cikksrtx.html