线程,进程和协程的区别
首先进程是最大的一个概念,他是操作系统的一个管理内存和程序的容器,比如你打开一个.exe文件,那么就创建这么一个容器,容器中加入各种运行所需要的二进制文件呀或者数据呀。
线程则是CPU调度运行的基本单位
协程的概念则比较特殊,他是用户态的一个运行单元,因为我们知道线程之间的切换需要在用户态和内核态之间切换,这个是非常耗时,消耗资源的。所以这时候就提出协程这个概念,我们不切换用户态和内核态,我们可以将线程1从执行A协程函数切换到执行B协程函数,这就达到了一个切换的目的,同时由于一致处于用户态中,所以资源消耗就较少。比如说你协程A遇到IO阻塞了,你就可以直接去执行了协程B了,不需要傻等IO完成
线程的几种状态:
New:初始化,但是还没有调用Start方法
Wait:等待Notify唤醒(处于等待队列)
Ready:一旦获取CPU资源就可以执行
Running:执行
也有地方将Ready和Running合为一个Runnable
Block:线程阻塞(处于同步队列)
Terminate:终止
具体说一下Wait和Block的区别:Wait是主动的一个行为,我不想跑了,我想等别的线程来叫我再说,block则是我想跑,但是没资源我跑不起来。Wait中的线程接收到Notify是从等待队列中来到同步队列中的,在同步队列中就可以竞争对象监视器了。
说说Runnable和Callable的区别
Runnable定义一个没有返回值Run方法函数
Callable定义一个有返回值Call方法函数
ThreadLocal是什么
ThreadLocal其实就是一个线程的局部/私有变量,这样做的好处显而易见,你就不需要关心线程安全了,这个变量专属于你,这个生命周期和线程的生命周期相同。但是比如说线程池中核心线程任务结束,不会被销毁,会被回收,那么我们的ThreaLocal也会被继续使用,这样就会产生一个ThreadLocal污染问题,那么我们就需要对ThreadLocal做一个重置回初始状态的操作。
说说线程池的几个参数
1.核心线程数:与线程池生命周期相同,线程池持续期间持续存在,不会被回收。
2.最大线程数:临时线程+核心线程的总数,代表最多可以创建几个线程处理任务
3.存活时间(值):代表非核心线程(临时线程)所能存在的时间值
4.存活时间(单位):代表非核心线程(临时线程)所能存在的时间单位
5.任务队列:代表到达最大线程数时,接受多少任务在阻塞队列中等待(BlockingQueue)
6.线程工厂:线程是通过何种方式产生的
7.拒绝策略:对于线程数量和任务队列都已经达到最大值之后,仍有新的任务该如何处理
这里总结一下顺序:
假设不断来大量任务
- 核心线程不断创建,直到达到最大值
- 转而将处理不了的任务放入任务队列
- 任务队列也满了,开始创建临时线程直到达到最大线程数
- 最大线程数也满了之后执行拒绝策略
线程池拒绝策略有哪几种
AbortPolicy:直接丢弃,抛出异常
DiscardPolicy:直接丢弃,不抛出异常
DiscardOldestPolicy:丢弃队列中最老的任务,然后重新尝试执行任务
CallerRunPolicy:让调用该线程的线程自己处理去吧