java 并发编程
cas
自旋 cas+死循环
yield+自旋
sleep +自旋
park+自旋
对象在内存中的布局
公平锁和非公平锁
ReentrantLock 源码
AQS
syschronized 关键字 底层原理
从各个层面分析:
1.java代码: synchronized
2.字节码的层面: monitorenter,moniterexit
3.jvm 执行过程中会自动升级 无锁--》偏向锁---》轻量级锁---》重量级锁
4.lock comxchg
1.什么是线程不安全
在多线程编程中,同时访问同一个共享可变的资源,由于线程的顺序不可控,所以容易产生线程安全问题。
2.如何解决线程安全问题
加锁,lock,synchronized
3.所有的并发模式,在解决线程线程安全问题时,采用的方案都是序列化访问临界资源。
ABA的问题 解决方案: 添加版本号
线程池的意义:
1.为什么使用线程池
线程是稀缺资源,它的创建和销毁是一个相对偏重和消耗资源的操作,而java线程依赖于内核线程,创建线程需要操作系统状态切换,为避免过度消耗资源,需要设法重用线程,线程池是一个线程缓存,负责对线程的分配,调度,调优,和监控。
2.线程池的优势:
1.重用线程,减少线程的创建和销亡,提高性能,提高响应速度。
3.什么时候使用线程池:
1.单个任务处理时间比较短
2.任务数量比较多
4.阻塞队列
在任意时刻,不管并发有多高,永远只有一个线程进行入队或出队操作,线程安全的队列
阻塞队列又分为有界队列和无界队列。
比如有界队列的长度是5 ,队列满时,只能进行出队操作,所有的入队操作必须等待,也就是阻塞
队列的长度为0 时,队列为空,只能进行入队操作,所有的出队操作必须等待,也就是阻塞
5.线程池的实现原理
线程池涉及的几个概念:核心线程的大小。线程池的大小,阻塞队列的大小,拒绝策略
流程: 提交任务,如果核心线程未满,创建线程执行任务,如果核心线程已满,判断阻塞队列是否已满,如果阻塞队列未满,把任务加入阻塞队列,如果阻塞队列已经满了,判断线程池是否已满,如果线程池未满,创建线程执行任务。如果线程池已满,执行拒绝策略。
ThreadPoolExecutor 构造方法的参数
int corePoolSize, 核心线程的大小
int maximumPoolSize, 线程池的大小
long keepAliveTime, 当前线程数>核心线程数,当一个线程的空闲时间达到keepalivetime,,则线程会终止。
TimeUnit unit,
BlockingQueue<Runnable> workQueue, 阻塞队列
ThreadFactory threadFactory, 线程工厂
RejectedExecutionHandler handler 拒绝策略
锁的状态
无锁态--->偏向锁--->轻量级锁(自旋锁,自适应锁)----->重量级锁
重量级锁 指向互斥量的指针
轻量级锁 指向线程栈中的Lock Record 指针
偏向锁 当前线程指针id
线程池 线程数的选取:
cpu密集型: 线程数=cpu的核数+1
IO密集型: 线程数=cpu的核数*(1+平均等待时间/平均工作时间)
参考:
1.https://www.jianshu.com/p/eac466494477-----------cas 原理
2.https://www.jianshu.com/p/da9d051dcc3d----aqs
3.https://blog.csdn.net/u012102536/article/details/103070769--- aqs源码分析
4.https://www.cnblogs.com/jxxblogs/p/11751944.html-------线程池的状态
5.https://www.jianshu.com/p/389b58856894----- java 线程池源码分析
6.https://www.jianshu.com/p/117571856b28---- java 线程池的实现源码分析
7.https://www.jianshu.com/p/063ebba64ec4---- java 线程池原理与Executor框架
8.https://www.jianshu.com/p/36eedeb3f912-----偏向锁,轻量级锁,重量级锁详解
9.https://www.bilibili.com/video/BV1s741127Gn?from=search&seid=14128259413075469454 ------ 偏向锁,轻量级锁,重量级锁视频
10.https://blog.csdn.net/lengxiao1993/article/details/81568130---- 偏向锁,轻量级锁,重量级锁的详解