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源码分析

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

六、简单应用场景

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

全部评论

相关推荐

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