线程池体系结构

线程池的组成
1.线程池管理器:用于创建并管理线程池
2.工作线程:线程池中的线程
3.任务接口:每个任务必须实现的接口,用于工作线程调度其运行
4.任务队列:用于存放待处理的任务,提供一种缓冲机制
Java中的线程池是通过Executor框架实现的,该框架用到了Executor,Executors,ExecutorService,ThreadPoolExecutor,Callable和Future,FutureTask这几个类.
关于这几个类之间实现关系的UML图:
在这里插入图片描述
线程池的体系架构

 java.util.concurrent.Executor:  负责线程的使用与调度的根接口
 		|--ExecutorService 子接口: 线程池的主要接口
 			|--ThreadPoolExecutor 线程池的实现类
 			|--ScheduledExecutorService 子接口: 负责线程的调度
 				|--SchediledThreadPoolExecutor: 继承ThreadPoolExecutor,实现ScheduledExecutorService

拒绝策略
线程池中的线程已经用完了,无法继续为新任务服务.同时等待队列也已经排满了,再也塞不下新任务了.这时候我们就需要拒绝策略机制合理的处理这个问题.
JDK内置的拒绝策略如下:
1.AbortPolicy: 直接抛出异常,组织系统正常运行.
2.CallerRunsPolicy: 只要线程池未关闭,该策略直接在调用者线程中,运行当前被丢弃的任务.显然这样做不会真的丢弃任务,但是,任务提交线程的性能极有可能会急剧下降.
3.DiscardOldestPolicy: 丢弃最老的一个请求,也就是即将被执行的任务,并且尝试再次提交当前任务.
4.DiscardPolicy: 该策略默默地丢弃无法处理的任务,不予任何处理.如果允许任务丢失,这是最好的一种方案.

注:以上内置拒绝策略均实现了RejectedExecutionHandler接口,若以上策略无法满足实际需要,完全可以自己拓展RejectExecutionHandler接口.

线程池创建方式
Java里面线程池的顶级接口是Executor,但是严格意义上讲Executor并不是一个线程池,而只是一个执行线程的工具.真正的线程池接口是ExecutorService.
为了便于跨大量上下文使用,此类提供了很多可调整的参数和拓展钩子(hook),.但是,强烈建议使用较为方便的工具类Executors工厂方法:

  1. ExecutorService newFixedThreadPool():创建固定大小的线程池,可以进行自动线程回收.
/**
 * @author chenjl
 * @date 2022/5/7
 * @desc ExecutorService newFixedThreadPool():创建固定大小的线程池,可以进行自动线程回收.
 */
public class NewFixedThreadPool {
    public static void main(String[] args) {
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
        for (int i = 0; i < 10; i++) {
            final int index = i;
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            fixedThreadPool.execute(()-> System.out.println(index));
        }
    }
}
  1. ExecutorService newCachedThreadPool():缓存线程池,线程数据量不固定,可以根据需求自动的更改数量.
/**
* @author chenjl
* @date 2022/5/7
* @desc ExecutorService newCachedThreadPool():缓存线程池,线程数据量不固定,可以根据需求自动的更改数量
*/
public class NewCachedThreadPool {

   public static void main(String[] args) {
       ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
       for (int i = 0; i < 10; i++) {
           final int index = i;
           try {
               Thread.sleep(10);
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
           cachedThreadPool.execute(()-> System.out.println(index));
       }
   }
}
  1. ExecutorService newSingleThreadExecutor():创建单个线程池.线程池中只有一个线程.
/**
 * @author chenjl
 * @date 2022/5/7
 * @desc ExecutorService newSingleThreadExecutor():创建单个线程池.线程池中只有一个线程
 */
public class NewSingleThreadExecutor {
    public static void main(String[] args) {
        ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
        for (int i = 0; i < 10; i++) {
            final int index = i;
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            singleThreadExecutor.execute(()-> System.out.println(index));
        }
    }
}
  1. ScheduledExecutorService newScheduledThreadPool():创建固定大小的线程,可以延迟或定时的执行任务.
/**
 * @author chenjl
 * @date 2022/5/7
 * @desc  ScheduledExecutorService newScheduledThreadPool():创建固定大小的线程,可以延迟或定
 */
public class NewScheduledThreadPool {
    public static void main(String[] args) {
        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
        for (int i = 0; i < 10; i++) {
            final int index = i;
            scheduledThreadPool.schedule(()->System.out.println(index), 3, TimeUnit.SECONDS);
        }

    }
}
  1. WorkStealingPoll():内部会创建ForkJoinPool,利用working-stealing算法,并行的处理任务,不保证处理的顺序
/**
 * @author chenjl
 * @date 2022/5/7
 * @desc WorkStealingPoll():内部会创建ForkJoinPool,利用working-stealing算法,并行的处理任务,不保证处理的顺序
 */
public class WorkStealingPollTask {
    private static Lock lock = new ReentrantLock();

    public static void main(String[] args) throws InterruptedException {
        ExecutorService workStealingPool = Executors.newWorkStealingPool(2);
        for (int i = 0; i < 100; i++) {
            final int index = i;
            workStealingPool.execute(() -> {
                System.out.println(Thread.currentThread().getName() + ":" + index);
            });
        }
        //让主线程休眠3秒,保证所有的任务执行完成
        TimeUnit.SECONDS.sleep(3);
    }
}

6.ForkJoinPool分支/合并框架(工作窃取)
其工作机制,在必要的情况下,将一个大任务,进行拆分(即fork环节)成若干个小任务(拆到不可再拆时),再将一个个的小任务运算的结果进行join汇总.
其本质是采用Work-Stealing算法,从某个线程池的任务缓冲队列中窃取任务去执行.在fork/join框架实现中,如果某个子任务由于等待另外一个子任务的完成而无法继续执行,那么处理该子任务的线程会主动去寻找其他尚未运行的子任务来执行,这种方式减少了线程的等待时间,提高了性能.图示:
在这里插入图片描述
demo由于时间原因暂时缺省.

注:线程池都是通过 ThreadPoolExecutor 创建出来的。而创建参数中有一个队列参数用于存放任务。而这些队列的长度都是Integer的最大值。这就导致在实际应用中会造成内存溢出情况。这也是为什么阿里巴巴 java 手册不允许使用 Executors 创建线程池的原因。建议自定义线程池.

线程池大小的选择
CPU密集型: 线程数=按照核数+1
IO密集型: 线程数=CPU核数*(1+平均等待时间/平均工作时间)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Java 高级程序员需要掌握以下几个知识体系: 1. Java 语言基础:包括语法、数据类型、控制结构、面向对象编程等。 2. 集合框架:Java 的集合框架是 Java 编程中非常重要的一部分,要求高级程序员对其熟练掌握。 3. 多线程:Java 中的多线程编程对于开发高性能的程序是非常重要的,高级程序员需要掌握多线程的实现方法以及常见的线程问题。 4. IO 流:Java 中的 IO 流用于读写数据,是编写高效程序的必备技能。 5. 网络编程:Java 是一种网络编程的首选语言,高级程序员需要掌握网络编程的方法,以及如何创建客户端/服务器应用程序。 6. 数据库编程:Java 编程中,数据库编程是非常重要的一部分,高级程序员需要掌握如何使用数据库,以及如何使用 Java 进行数据库编程。 7. 设计模式:设计模式是高级程序员必备的知识,学习设计模式可以帮助编写出优秀、易维 ### 回答2: Java是一种跨平台的编程语言,在进行高级程序开发时,需要掌握一系列的知识体系。下面我将详细介绍Java高级程序员需要掌握的知识体系结构。 1. Java语言基础:学习Java语言的核心特性,包括基本语法、数据类型、运算符、流程控制、异常处理等。理解Java面向对象的特性,如封装、继承、多态等,同时熟悉Java内存管理和垃圾回收机制。 2. 数据结构与算法:掌握常见的数据结构,如数组、链表、栈、队列、树、图等,理解它们的原理和应用场景,并能够分析和解决常见的算法问题。 3. 多线程与并发:熟悉Java多线程编程,了解线程的生命周期、同步与互斥、线程安全等概念。掌握Java提供的线程相关的API和工具,能够编写高效、安全的多线程代码。 4. 网络编程:掌握Java网络编程的基本知识,包括Socket编程、TCP/IP协议、HTTP协议等。理解网络通信的原理,并能够开发基于网络的应用程序。 5. 数据库与持久化:熟悉关系型数据库的基本原理和常用操作,如SQL语句编写、事务控制、索引等。了解Java的持久化技术,如JDBC、Hibernate、MyBatis等,能够进行数据库的连接和操作。 6. 设计模式:熟悉常见的设计模式,如单例模式、工厂模式、观察者模式等,理解它们的应用场景和实现原理,能够根据需求选择和应用适当的设计模式。 7. 框架与中间件:熟悉常用的Java框架和中间件,如Spring、Spring MVC、Spring Boot、MyBatis等,能够利用这些框架快速开发高效、可维护的应用程序。 8. 性能调优与监控:掌握Java性能调优的基本方法和工具,能够定位和解决应用程序的性能瓶颈,并进行性能调优优化。了解监控工具的使用,能够进行应用程序的监控和故障排查。 总之,Java高级程序员需要具备扎实的Java语言基础,熟悉常用的开发工具和框架,同时还需要理解计算机基础知识和软件工程原理,能够设计和开发复杂的应用程序,并具备分析和解决实际问题的能力。 ### 回答3: Java高级程序需要掌握以下知识体系: 1. 面向对象编程(OOP):理解面向对象编程的基本概念、原则和思想,包括封装、继承和多态等概念。掌握类、对象、方法、属性、接口等概念和使用。 2. Java核心库:熟悉Java标准库的各个模块,如集合框架、多线程、输入输出、异常处理等。熟悉常用的类和接口,并能灵活运用它们解决问题。 3. 设计模式:掌握常见的设计模式,如单例模式、工厂模式、观察者模式等。了解它们的原理和应用场景,能够用设计模式来解决实际问题。 4. 数据库和SQL:熟悉数据库的基本概念和操作,了解SQL语言的基本语法。能够通过Java程序与数据库进行交互,实现数据的增删改查操作。 5. Web开发:掌握基本的前端开发技术,比如HTML、CSS、JavaScript等。熟悉Java Web开发的框架和技术,如Servlet、JSP、Spring MVC等。了解HTTP协议和前后端交互的原理。 6. 网络编程:理解网络编程的基本概念和原理,能够使用Java进行网络通信。了解TCP/IP协议、Socket编程等相关技术。 7. 并发编程:了解并发编程的基本概念和原理,能够正确地使用多线程和锁机制。熟悉Java中的线程池、同步工具等并发编程相关的类和接口。 8. 性能调优:了解性能调优的基本原则和方法,能够对Java程序进行性能分析和优化。熟悉Java中的性能调优工具和技术。 9. 安全性:了解Java程序安全性的相关知识,包括防止代码注入、数据加密等。理解常见的安全漏洞和攻击方式,并能够采取相应的安全措施。 10. 测试和调试:熟悉测试和调试的基本原则和方法,能够编写有效的单元测试和集成测试。熟练使用调试工具,能够快速定位和解决程序中的问题。 总结起来,Java高级程序员需要掌握面向对象编程、Java核心库、设计模式、数据库和SQL、Web开发、网络编程、并发编程、性能调优、安全性以及测试和调试等知识体系。这些知识体系构成了Java高级程序员的核心能力,能够帮助他们设计、开发和维护复杂的Java应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叶枫^_^

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值