线程个人总结(面试使用)
https://mp.weixin.qq.com/s/h6SMb1y7XVJa8jc-Xu3LYw 详解线程池
一。创建线程的方式
1.继承thread类创建线程,重写run方法
2.实现runnable接口,重写run方法
3.实现callable接口通过call方法
4.使用线程池创建
前面两种可以归结为一类:无返回值,原因很简单,通过重写run方法,run方式的返回值是void,所以没有办法返回结果
后面两种可以归结成一类:有返回值,通过Callable接口,就要实现call方法,这个方法的返回值是Object,所以返回的结果可以放在Object对象中
二。sleep wait
wait:导致当前的线程等待,直到其他线程调用此对象的notify和notifyAll方法。(可以设置超时时间)是属于object类,
sleep:属于thread类,当指定时间到了自动恢复,
wait通常使用于线程的交互;join实现线程的排序
三。notify notifyAll 都是java.lang.objecthttps://mp.weixin.qq.com/s/Tbjy_FAtNxE6YNGZdIlp5
notify:唤醒在此对象监视器上等待的单个线程
notifyAll:唤醒在此对象监视器上等待的所有线程
四。run start
start:开启一个线程。指的是一个线程状态。必须开启才可以执行run
run:线程调用的方法
五。线程池 threadPoolExecutor
https://blog.csdn.net/programmer_at/article/details/79799267
1.为什么使用线程池:减少资源开销,创建和销毁操作。提高线程的可管理性
2.四种线程池类型:
定长线程池:fixedThreadPool :设置线程的数量
可缓存线程池 cachedThreadPool 无线扩大的线程池,适合执行时间短的任务。
单一线程池 singleThreadExecutor 只会创建一条工作线程处理任务,采用阻塞队列方式
可调度线程池 ScheduledThreadPool 用来处理延时任务或定时任务
3.源码解析:常用参数
capacity:使用高3位标识运行状态:-1到3
running:接收新任务,并处理任务队列中任务 -1
shutdown:不接收新任务,但处理任务列的任务 0
stop:不接收任务,不处理任务队列,同时中断所有进行中任务 1
tidying:所有任务已被终止,工作线程数量为0,到达该状态会执行terminated
terminated:terminated执行完毕
corePoolSize:最小存活的工程线程数量,
4.拒绝策略:
当队列满了会触发拒绝策略,有四种处理放式。抛错,抛弃线程等操作
六。ThreadLocal
1.在多线程中类似于synchronized。只是锁是保证统一时间只有一个线程工作,锁定代码块。资源是共享的。ThreadLocal是每个线程都会有自己的变量副本,线程间互不影响。存在访问的对象可能都不一样。
2.原理:每个线程都维护自己的一个map,键是threadLocal类型,值是object类型。
它的内部类是ThreadLocalMap、
七:线程源码 https://mp.weixin.qq.com/s/Axww5MvevL81e6r8xXZlDA
1.核心:线程处理池 线程等待池
2.参数:corepoolSize 核心线程数,一直保持的线程
最大线程数 等任务多时,自动扩充线程数
keepalievdtime 等待线程存活时间
uilt 时间 毫秒等
handler 有拒绝策略,等待任务多时,可以选择抛错或者不处理,不执行等四种方案。
3.executor是线程顶级接口,是执行线程的
executorService :线程池就看,提供了很多方法
executors:创建线程池用的工厂类
4.四种线程池:
可缓存线程池:没有核心线程,无线扩大。执行是60ms的
单例线程池:只有一个线程工作,使用与有顺序的线程
定长线程池:指定线程大小。有核心线程和非核心线程数
周期性线程池:执行定时任务。有核心线程,非核心线程无线扩大
5.线程池减少线程的创建和销毁,节省时间和性能开销。而且线程池效率高,可以控制
传照片多张。用线程池更快
6。提交任务:executor 提交任务没有返回值,runnable的实例
submit 返回一个future类型的对象,可以判断任务执行结果。get方法获取返回结果
7.关闭任务:shutdown和shutdownNow 一个是调用shutdown方法一个是stop方法
tryclose(true)设置线程运行完之后关闭,防止有的没执行完就关闭了线程
8.线程池配置:1.根据cpu密集型任务;任务优先级;任务执行时间长短
9.线程池提供的一些参数可以监控线程执行效率
10.三种阻塞队列:
BlockingQueue<Runnable> workQueue = null;
workQueue = new ArrayBlockingQueue<>(5);//基于数组的先进先出队列,有界;定长,缓存队列如果多久queue full异常,少就加队尾
workQueue = new LinkedBlockingQueue<>();//基于链表的先进先出队列,无界
workQueue = new SynchronousQueue<>();//无缓冲的等待队列,无界
八:守护线程
用户线程:java程序创建的一个线程
守护线程:jvm垃圾回收就是一个守护线程,守护线程创建的也是守护线程。就是后台程序执行,到jvm不在执行且退出,守护线程就没了。就是一直保持在。
九。当线程池中某个线程失败,其他线程会怎样
https://www.geek-share.com/detail/2755019420.html
https://blog.csdn.net/Fmuma/article/details/79890180
不影响其他线程,线程间都是独立的
https://blog.csdn.net/not_in_mountain/article/details/77861399
失败时候捕获异常:1.通过excutor的,uncaughtexctptionHandler
2.future获取的事submit,根据返回的信息。
十。qps和tps
qps:每秒查询率。对于请求,响应的次数
tps:每秒请求过来开始计时到响应结束完成事务的个数;包括三个阶段:接收请求,内部处理,响应出去
服务器CPU核数为4核,一个任务线程cpu耗时为20ms,线程等待(网络IO、磁盘IO)耗时80ms,那最佳线程数目:( 80 + 20 )/20 * 4 = 20
最佳线程数目 = ((线程等待时间+线程CPU时间)/线程CPU时间 )* CPU数目
十一。上下文切换
在多线程内核中其实都是cpu控制单线程在操作,只是线程之间存在切换。这种来回使用线程叫做上下文切换。 一个cpu在 同一时刻只会执行一个线程。上下文切换是需要时间的。所以线程的数量并不一定越多越好。提高cpu利用率和切换次少更少。
十二。线程123,保证2在1完成后执行
使用join实现
十三。yield
使得当前线程从执行状态变为可执行状态,就是那个线程可以执行,就看系统分配
打断当前线程,使所有线程斗鱼机会执行
十四。堆内存溢出时,其他线程怎么样
https://mp.weixin.qq.com/s/24cEE1PtyEzFOcZUIERjvw
一个线程OOM后,其他线程还能运行
其实发生OOM的线程一般情况下会死亡,也就是会被终结掉,该线程持有的对象占用的heap都会被gc了,释放内存。因为发生OOM之前要进行gc,就算其他线程能够正常工作,也会因为频繁gc产生较大的影响。
- 设计模式个人总结(面试使用)
- UNICODE编码细节与个人使用总结
- wpf中使用MVVM模式进行开发,View与ViewModule的交互个人总结
- vim常用的个人使用总结
- UNICODE编码细节与个人使用总结
- Android中的JSON使用个人总结【半月谈投稿】
- java事件监听器使用小结(个人总结,有错请指)
- C#中yield关键字的使用个人总结
- UML学习个人总结——ROSE使用
- Win 7下使用DNW方法(个人总结)
- Android NDK 个人使用状况总结
- 个人不完全使用StreamBase的总结
- UITableView个人使用总结【前篇-增量加载】
- git个人使用过程整理和总结
- django 学习个人总结 之admin后台的使用,操作
- 使用boost线程定时器作为后台线程来切换主循环程序状态方法总结
- spring的aop用法个人使用总结
- VIM的使用指南(个人总结)
- 使用git/github管理ios项目 个人总结
- iphone 线程总结— detachNewThreadSelector的使用