多线程
2022-05-02 21:56:57 0 举报
AI智能生成
java多线程 继续更新
作者其他创作
大纲/内容
介绍
作用
基础
runnable的实现
多线程安全
线程安全是怎么一回事
为什么会有这样的一些线程安全的问题
那些手段可以解决这些线程安全的问题
synchronized 的实现(同步代码块)
1. 偏向锁:就是该线程占有的锁 还是该线程来做使用的话 会更快一点 因为内存中有了锁的结构 指针。 比如一个人干的很久了,再让他干这个工作会更块一点!
2. 轻量级锁:对synchronized 的优化 ,先不悲观的去操作这个锁 而是采用一种Cas方式去获取这个锁,如果发现这个锁被其他的线程占用,再去排队获取这个锁 给他设置为重量级的锁:(乐观锁机制)
3. 重量级锁:原本之前的jdk版本 直接给标识 为已占有的标识 (开销比较大一点)
可以放在方法上 可以放在对象上
区别:锁的粒度不同
比如咱们这个业务里面 10行代码 三行需要做同步执行,其他行就可以不做锁 做--**锁分离**--的操作 目的减少 锁的粒度!
2. 轻量级锁:对synchronized 的优化 ,先不悲观的去操作这个锁 而是采用一种Cas方式去获取这个锁,如果发现这个锁被其他的线程占用,再去排队获取这个锁 给他设置为重量级的锁:(乐观锁机制)
3. 重量级锁:原本之前的jdk版本 直接给标识 为已占有的标识 (开销比较大一点)
可以放在方法上 可以放在对象上
区别:锁的粒度不同
比如咱们这个业务里面 10行代码 三行需要做同步执行,其他行就可以不做锁 做--**锁分离**--的操作 目的减少 锁的粒度!
volatile关键字
1. 每次读取数据都强制从主内存中获取
2. 使用的场景:单个线程写,多个线程读
3. 原则:能不用就不用
4. 替代的方案:Atomic原子操作类
2. 使用的场景:单个线程写,多个线程读
3. 原则:能不用就不用
4. 替代的方案:Atomic原子操作类
线程池原理与使用
为什么要用线程池,直接一个一个的new线程不行吗?
1. 主要是线程的资源对于系统来说是占用的资源**比较多** **比较重量**级的一个资源
2. 这类资源更倾向于个池化的线程池,直接维护好池化的线程池,用的时候从里面取
3. 如果自己创建线程的话需要维护线程的多少 大小,因为物理资源是有限的
2. 这类资源更倾向于个池化的线程池,直接维护好池化的线程池,用的时候从里面取
3. 如果自己创建线程的话需要维护线程的多少 大小,因为物理资源是有限的
那么线程池是怎么处理大量过来的需要并行计算的业务呢?
首先要弄一个基础设施业务,线程池是很复杂的,好在jdk已经封装了一些api 包 jdk 已经实现了抽象的线程池的定义
jdk线程池:
.Excutor:执行者顶层接口
void execute(Runnable command):执行可运行的任务
.ExcutorService:接口api
继承了excutor 接口
添加了一些其他的方法
比如: void shutdown() 方法 :停止接受新的任务,原来任务继续执行
*场景:优雅停机维护*
List<Runnable> shutdownNow():停止接受新的任务 ,强制停止之前的任务
boolean awaitTermination(timeOut, unit):阻塞当前线程,返回是否线程都执行完
submit()方法
> submit方法->有返回值,用Future封装
>
> execute 方法->无返回值
>
> submit 方法还异常可以在主线程中get 捕获到 (注意部分异常 比如算术异常 会被吞掉)
>
> execute 方法执行任务是捕捉不到异常的
ThreadFactory:线程工厂(设计模式:工厂模式)
ThreadPoolExecutor:调用线程的参数 一般使用这个
判断corePoolSize(创建)
判断第一个运行线程数有没有达到 核心线程数 达不到新建一个出来
加入workQueue
如果达到!缓存队列排队 !
判断maximumPoolSize(创建)
如果缓存队列也满了,判断是否到达最大线程数
执行拒绝策略处理器
Excutors:工具类,创建线程
创建线程池的方法:
newSingleThreadExecutor
创建一个单线程的线程池。这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因 为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。
newFixedThreadPool
创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。线程池的大小一旦达到最 大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。
newCachedThreadPool
创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程,
那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。此线程池不会 对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM))能够创建的最大线程大小。
那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。此线程池不会 对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM))能够创建的最大线程大小。
newScheduledThreadPool
创建一个大小无限的线程池,此线程池支持定时以及周期性执行任务的需求。、
创建固定线程池的经验
不是越大越好,太小肯定也不好:假设核心数为N
1、如果是 CPU 密集型应用,则线程池大小设置为
N或 N+1
2、如果是IO密集型应用,则线程池大小设置为2N 或2N+2
1、如果是 CPU 密集型应用,则线程池大小设置为
N或 N+1
2、如果是IO密集型应用,则线程池大小设置为2N 或2N+2
0 条评论
下一页