`
xiaoZ5919
  • 浏览: 405483 次
  • 性别: Icon_minigender_1
  • 来自: 安平人@北京
博客专栏
Group-logo
Netty学习笔记
浏览量:73254
社区版块
存档分类
最新评论

Java并发编程JUC源码学习之ThreadPoolExecutor

 
阅读更多

 ThreadPool的优点,比如资源的控制以及不用频繁的创建线程等就不用多说了。主要来讨论一下ThreadPoolExecutor的几个关键参数以及对task的添加以及线程的管理。它有这么个重要的参数corePoolSize、maximumPoolSize、keepAliveTime和taskqueue。

corePoolSize   线程池维持处于Keep-alive状态的线程数量。如果设置了allowCoreThreadTimeOut为true,该值可能为0。
maximumPoolSize   线程池中可维持线程的最大值。
keepAliveTime   当线程池中线程数量大于 corePoolSize  时,如果某些线程的空闲时间超过该值就会终止,直到线程数小于等于corePoolSize。
    1. 添加一个task的过程
    当要添加一个新的task,如果当前线程数小于 corePoolSize,直接添加一个线程,即使当前有空闲的线程。否则添加队列中。如果队列满了呢?则会判断当前线程数是否小于maximumPoolSize,如是则添加一个新的线程用来执行该task。如果超出最大线程数,那就只能reject了。
       
 int c = ctl.get();
        // 当前线程数小于corePoolSize
        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);
        }
       //队列满时添加新的线程,如果线程数超过maximumPoolSize则reject
        else if (!addWorker(command, false))
            reject(command);
 
     使用addWorker(),来创建新的线程并传入的task作为第一个task执行。由此来看只有队列满时才会创建大于corePoolSize的线程。
 
    2.   KeepAliveTime是如何实现的呢?
       keepAliveTime的职责时,当线程池的队列满了,创建了多于corePoolSize的线程,这时处于节省资源的目的,会杀死多于corePoolSize空闲时间大于keepAliveTime的线程。它是如何做到呢?我们知道Woker时从taskQueue不断地轮询获取task并执行。如果获取不到task取到null时则退出循环结束线程。大概源码是这样的。
     
 try {
           //当取到task为null,跳出循环结束线程
            while (task != null || (task = getTask()) != null) {
                w.lock();
                clearInterruptsForTaskRun();
                 //此处省略,主要是执行task.run
             }
 
      关键是看看getTask()如何返回null,该方法的comments列出几种返回null并减少当前线程数的情景。我们在这里只关心keeAliveTime的实现。
      
boolean timedOut = false; // Did the last poll() time out? 该变量标识从taskqueue中取任务是否超时,如果超时则返回null
  
       retry:
        for (;;) {
            int c = ctl.get();
            int rs = runStateOf(c);


            // Check if queue empty only if necessary.
            if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
                decrementWorkerCount();
                return null;
            }


            boolean timed;      // Are workers subject to culling?


            for (;;) {
                int wc = workerCountOf(c);
                timed = allowCoreThreadTimeOut || wc > corePoolSize;//线程数大于corePoolSize满足了杀死空闲线程的条件
                //第一次执行到这里,由于timeOut为false,跳出内循环执行从queue取任务
                if (wc <= maximumPoolSize && ! (timedOut && timed))
                    break;
                //第二次执行的时候由于timedOut为true,不会跳出内循环。执行下面的代码
               //将当前线程数减1并返回null致使该线程终止
                if (compareAndDecrementWorkerCount(c))
                    return null;
                c = ctl.get();  // Re-read ctl
                if (runStateOf(c) != rs)
                    continue retry;
                // else CAS failed due to workerCount change; retry inner loop
            }


            try {
               //timed为true,这段code是实现空闲时间超过keepalivetime就被终止的精华所在。
              // 在给定的keepalivetime时间内从阻塞队列中取任务。如timeout则返回null
                Runnable r = timed ?
                    workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
                    workQueue.take();
                if (r != null)
                    return r;
                timedOut = true;//如从queue中取任务超时则为true
            } catch (InterruptedException retry) {
                timedOut = false;
            }
        }
 
1
1
分享到:
评论

相关推荐

    JUC并发编程与源码分析视频课.zip

    《JUC并发编程与源码分析视频课》是一门深入探讨Java并发编程的课程,主要聚焦于Java Util Concurrency(JUC)库的使用和源码解析。JUC是Java平台提供的一组高级并发工具包,它极大地简化了多线程编程,并提供了更...

    java并发编程艺术源码-ArtConcurrentBook:JAVA并发编程的艺术

    《Java并发编程艺术》是一本深入探讨Java多线程与并发编程的经典著作,它涵盖了...通过深入学习和实践《Java并发编程艺术》的源码,开发者可以更好地理解和应用Java并发编程技术,提高多线程环境下的程序性能和稳定性。

    并发编程、juc工具包源码分析笔记

    在深入学习 Java 并发编程时,还需要关注线程安全、锁机制(如 synchronized 关键字、ReentrantLock 等)、并发容器(如 ConcurrentHashMap、ConcurrentLinkedQueue 等)、原子变量(AtomicInteger、AtomicReference...

    juc源码视频教程最全

    Java并发编程是现代Java开发中的重要组成部分,Java并发 utilities(JUC)库是Java平台标准版(Java SE)的一部分,提供了强大的工具和...通过学习,你将能够更好地掌握Java并发编程,编写出高效、稳定的多线程应用。

    Java并发编程实践中(中+英+例子源码)

    这本书“Java并发编程实践中(中+英+例子源码)”提供了深入理解Java并发机制的宝贵资源。下面我们将详细探讨其中涉及的一些关键知识点。 1. **线程与进程**:在并发编程中,线程是程序执行的基本单位,而进程则是...

    java高并发源码-java-concurrent:Java高并发,JUC,相关源码。1、马士兵高并发视频源码(听课时练习)

    总之,Java并发编程是每个Java开发者必备的技能之一,而"java-concurrent"项目和相关的学习资源为我们提供了一个很好的实践和学习平台。通过深入研究源码,我们可以更好地掌握Java并发编程的核心概念和最佳实践,...

    JUC并发编程学习笔记(硅谷)

    Java并发编程是Java开发中的重要领域,特别是在大型分布式系统或者高并发应用中,对线程安全和性能优化的理解与实践至关重要。"JUC并发编程学习笔记(硅谷)"很可能包含了关于Java并发工具集(Java Util Concurrency, ...

    JUC并发编程.rar

    总之,"JUC并发编程.rar"是一个宝贵的资源,它涵盖了Java并发编程的关键方面,无论你是想提升你的并发编程技能,还是在面临并发问题时寻找解决方案,这个资料都将大有裨益。通过深入学习和实践,你将能够更好地理解...

    并发学习并发学习并发学习并发学习并发学习

    3. **Java并发工具集JUC(java.util.concurrent)**:JUC是Java并发编程的重要库,包含线程池、并发容器、并发集合以及同步工具等。其中,`ExecutorService`和`ThreadPoolExecutor`用于管理线程池,`Semaphore`用于...

    juc学习代码。。。。

    在这个"juc学习代码"的资源中,我们很显然会接触到Java并发编程的核心概念和实践。 首先,JUC库中的`java.util.concurrent`包包含了大量并发工具类,如`Semaphore`(信号量)、`CyclicBarrier`(循环屏障)、`...

    JUC+课程源码+线程操作

    Java并发编程是Java开发中的重要领域,而JUC(Java Util Concurrency)是Java平台提供的一套高级并发工具包,它极大地简化了多线程和并发编程。本课程资源主要围绕JUC进行展开,通过样例源码帮助学习者深入理解和...

    juc-learn:juc相关源码的分析以及使用介绍

    Java并发编程是Java开发中的重要领域,而JUC(Java Util Concurrency)是Java提供的一套强大的并发工具包,它包含在`java.util.concurrent`包下。本项目"juc-learn"专注于JUC相关源码的分析和使用介绍,旨在帮助...

    JavaCommon:Java基础用法,集合,线程,JUC,jdk5--8各个版本特性。

    JavaCommon 是一个涵盖Java基础知识和进阶特性的项目,它主要关注Java编程语言的基础用法、集合框架、多线程处理以及Java并发工具集(JUC)。该项目还深入解析了从JDK 5到JDK 8各版本的重要特性,为开发者提供了丰富...

    jdkLearning:阅读java原始代码包含:集合,JUC,Executor体系

    2. **Java并发工具包(JUC)**: JUC全称为Java Util Concurrency,是Java 5引入的一套强大的并发编程工具。它包含了诸如Semaphore(信号量)、CyclicBarrier(回环屏障)、CountDownLatch(倒计时器)和Exchanger...

Global site tag (gtag.js) - Google Analytics