线程池
线程
什么是线程?
线程是资源调度的最小单位,也是轻量级进程 LWP
(Light Weight Process)
创建线程的四种方式:
1、继承Thread类创建线程类
2、从线程池中获取
3、实现Runnable接口
Runnable接口不会返回结果或抛出检查异常,但是Callable接口可以
4、实现Callable接口和Future创建线程
Java线程状态变化:
线程创建之后它将处于 NEW(新建) 状态,调用 start()
方法后开始运行,线程这时候处于 READY(可运行) 状态。可运行状态的线程获得了 CPU 时间片(timeslice)后就处于 RUNNING(运行) 状态。
什么是线程池
所谓线程池,就是一次性创建出多个线程,当一个任务到来的时候可以直接从线程池中获取一个线程来执行任务,不需要去创建;当任务执行完毕,直接将线程还给线程池,不需要销毁。这里做避免了频繁的创建和销毁带来的消耗。
线程池的核心就是生产者-消费者模型
- 生产者(调用submit()或execute()方法将任务task放入队列)
- 消费者(worker线程)循环从队列中取出任务处理任务(执行task.run())
线程池的好处
池化技术: 在线程池、数据库连接池、HTTP连接池中都有使用,主要是为了减少每次获取资源的消耗,提高对资源的利用率。
**第一:降低资源消耗。**通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
**第二:提高响应速度。**当任务到达时,任务可以不需要等到线程创建就能立即执行。
**第三:提高线程的可管理性。**线程是稀缺资源,如果无限制地创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一分配、调优和监控。
创建线程池
- 通过构造方法实现
- 通过Executor框架的工具类Executors来实现
- 通过
ThreadPoolExecutor
的方式
FixedThreadPool
创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待
SingleThreadExecutor
创建一个单线程化的线程池,它只会唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO,LIFO,优先级)执行
CachedThreadPool
创建一个可缓存的线程池,如果线程池长度超过处理需求,可灵活回收空闲线程,若无可回收,则新建线程
ScheduledThreadPool
创建一个定长线程池,支持定时及周期性任务执行
线程池实现的原理
线程池的实现过程没有用到Synchronized关键字,用的都是volatile,lock和同步阻塞队列,atomic相关类,FutureTask等等,因为后者的性能更优。
线程优点:1. 线程重用;2. 控制最大并发数;3. 管理线程
1. 线程复用过程
2. 控制最大并发数
3. 管理线程
线程池的工作流程
判断核心线程是否已满——> 判断阻塞队列是否已满——>线程池是否已满——>按照策略处理无法执行功能的任务
线程池工作流程
线程池刚创建时,里面没有一个线程。任务队列是作为参数传进来的。不过,就算队列里面有任务,线程池也不会马上执行它们。
当调用 execute() 方法添加一个任务时,线程池会做如下判断:
如果正在运行的线程数量小于
cor