这是我参与更文挑战的第1天,活动详情查看:更文挑战
一、线程和进程
- 进程:程序执行的一次执行过程,是系统运行程序的基本单位;系统运行一个程序即是一个进程从创建、运行、消亡的过程。
- 线程:是进程里面更小的执行单位, 一个程序运行过程中会产生多个线程;多个线程间共享 堆、方法区;每个线程独享 程序计数器、虚拟机栈、本地方法栈。
二、线程的几种状态(6种)
| 状态 | 状态名称 | 说明 |
|---|---|---|
| NEW | 初始状态 | 该状态线程创建完毕,但还没调用start()方法 |
| RUNNABLE | 运行状态 | java 线程将 操作系统 中的【就绪】和【运行】两种状态 统称为 “运行中”】 |
| BLOCKED | 阻塞状态 | 表示<当前线程> 阻塞于【锁】 |
| WAITING | 等待状态 | 进入该状态<当前线程>需要等待<其他线程>做出一些特定的动作(通知或中断) |
| TIME_WAITING | 超时等待状态 | 该状态不同于WAITING,它是可以在指定的时间自行返回的 |
| TREMINATED | 终止状态 | 表示<当前线程>已经执行完毕 |
gantt
title 项目V5.0
dateFormat YYYY-MM-DD
section 里程碑1
立项 :a1, 2021-04-15, 20d
公众号 :after a1 , 25d
section 里程碑2
Task1 :2021-06-01 , 15d
task2 :10d
section 里程碑3
task1 :2021-07-16 , 15d
task2 :15d
section 里程碑4
task1 :2021-09-01 , 15d
task2 :20d
section 里程碑5
节点1 :2021-12-01 , 15d
节点2 :20d
三、线程池概念及好处
池化技术
数据库连接池、HTTP连接池、线程池....
好处
- 减少每次获取资源的消耗,提高对资源的利用率。
- 提供了一种限制和管理资源(包括执行一个任务)。
- 每个线程池还维护一些基本统计信息,例如已完成任务的数量。
四、线程的创建方式(4种)
1. 继承Thread类
class Thread: public void run(); //@Override 方法无返回值
2. 实现Runnable接口
interface Runnable: public abstract void run(); 方法无返回值
3. 使用Callable和Future创建线程
interface Callable: V call() throws Exception; 方法有返回值
4. 使用线程池例如用Executor框架、阿里推荐的ThreadPoolExecutor 创建线程
Executor(不推荐)ThreadPoolExecutor(推荐)
五、Executor框架创建线程(不推荐)
-
FixedThreadPool(可重用固定线程数的线程池) FixedThreadPool 使用无界队列 LinkedBlockingQueue(队列的容量为 Integer.MAX_VALUE)作为线程池的工作
-
SingleThreadExecutor(单线程化线程池) 允许请求的队列长度为 Integer.MAX_VALUE ,可能堆积大量的请求,从而导致 OOM。
-
CachedThreadPool(可缓存的线程池) 会根据需要创建新线程的线程池(线程个数为0-Integer.MAX_VALUE)
-
ScheduledThreadPool(定时及周期执行的线程池)
六、ThreadPoolExecutor创建线程(推荐)
1.构造方法及主要参数
public ThreadPoolExecutor(
int corePoolSize, //线程池的核心线程数量
int maximumPoolSize, //线程池的最大线程数
long keepAliveTime, //当线程数大于核心线程数时,多余的空闲线程存活的最长时间
TimeUnit unit, //keepAliveTime参数的时间单位
BlockingQueue<Runnable> workQueue, //任务队列,用来储存等待执行任务的队列
ThreadFactory threadFactory, //线程工厂,用来创建线程,一般默认即可
RejectedExecutionHandler handler //拒绝策略,当提交的任务过多而不能及时处理时,我们可以定制策略来处理任务) {
......
}
ThreadPoolExecutor 3 个最重要的参数:
- corePoolSize : 核心线程数线程数定义了最小可以同时运行的线程数量。
- maximumPoolSize : 当队列中存放的任务达到队列容量的时候,当前可以同时运行的线程数量变为最大线程数。
- workQueue: 当新任务来的时候会先判断当前运行的线程数量是否达到核心线程数,如果达到的话,新任务就会被存放在队列中。
ThreadPoolExecutor其他常见参数:
- keepAliveTime:当线程池中的线程数量大于 corePoolSize 的时候,如果这时没有新的任务提交,核心线程外的线程不会立即销毁,而是会等待,直到等待的时间超过了 keepAliveTime才会被回收销毁;
- unit : keepAliveTime 参数的时间单位。
- threadFactory :executor 创建新线程的时候会用到。
- handler :饱和策略。
2.线程池的几种工作队列
- ArrayBlockingQueue(有界队列)
- LinkedBlockingQueue(可设置容量队列)
- DelayQueue(延迟队列)
- PriorityBlockingQueue(优先级队列)
- SynchronousQueue(同步队列)
3.四种拒绝策略
七、几种常用方法比较
- Callable接口和Runnable接口
- execute()与submit()方法
- shutdown()与shutdownNow()方法
- isTerminated()与isShutdown()方法
八、如何保证线程按顺序执行
- 单线程化线程池SingleThreadExecutor
- 线程的join()方法
- 线程的wait()方法
- 线程的CountDownLatch(倒计数)方法
- 线程的Semaphore(信号量)方法
- 线程的Condition(条件变量)方法
- 线程的CyclicBarrier(回环栅栏)方法