java多线程:ThreadPoolExecutor线程池简介和源码分析

一、话题引入

    前几天在实习公司写完一个简单爬虫项目,也为公司爬取了一些数据。因为项目是javase的,也比较简单,所以就没有用spring框架写。都是自己利用一些类自己封装了一些工具类,其中就自己利用ThreadPoolExecutor类实现了简单线程池工具类,主要是方便使用。现在项目也暂时写完了,使用之后也的确对并发编程和ThreadPoolExecutor更加清晰了,写下这篇做个记录吧。

一、线程池简单介绍

    首先还是简单介绍一下为什么要使用线程池做并发编程吧。
    我们创建线程的根本方式其实就两种,一种是实现Runnable,另一种是实现Callable。两者的区别是Runnable中的run方法是没有返回值的,Callable是有返回值的。或许你会说不是还有继承Thread的方式吗?是的,你说的没错。的确还有,而且还有利用ExecutorService的两个方法创建线程呢。不过这些都是基于这两个接口的。比如继承Thread的方式创建线程,其实也就是实现了Runnable,只不过是多帮你写了一些属性和方法,你可以直接调用,比如设置名字之类的。而且使用这种方式创建线程缺点是不能继承其他类,因为java不支持多继承。多线程并发编程你当然可以选择不使用线程池来进行,不过在这里我使用了线程池主要是因为爬虫是进行一次短暂的http请求获取返回的网页数据的操作。对于这种会话时间短的是非常适合线程池的,因为这样可以重用线程,避免资源浪费在线程的创建和销毁。
    线程池简单来说就是一个类,这个类内部有一个容器来保存管理一定数量的线程对象,还为了维护这些线程做了一些其他的事情。可以有如下三个简单好处:
  1. 实现线程的复用,可以避免时间和资源浪费在创建线程和销毁线程上。
  2. 控制并发线程的线程数,可以有效的避免大量的线程池争夺CPU资源而造成堵塞。
  3. 提高线程的可管理性,线程是稀缺资源,如果无限制地创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一分配、调优和监控

二、线程池实现原理

    线程池的实现主要通过一定的策略维护一组线程对象,利用主要有以下参数:
  1. 核心线程数
  2. 最大线程数
  3. 闲置线程存活时间
  4. 闲置线程存活时间的单位
  5. 任务线程队列
  6. 创建线程的工厂
  7. 拒绝策略
    线程运行的原理主要是下面这张图(图片来自java并发编程的艺术一书)

主要运行

三、线程池相关类

四、核心实现类ThreadPoolExecutor源码分析

五、自己手动实现自定义的异常处理策略

六、简单应用场景

七、参数设计和简单调优
八、总结

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务