多线程理解杂记
2017-08-01 10:15
246 查看
个人理解:无锁线程安全的依据:利用volatile和final禁止重排序,
第二个操作位volatile写时或第一个操作位volatile读时, 不允许重排序
final基础类型:写不能排到构造函数之外。(保证别的线程引用该对象时,final变量已经被赋值,而非fianl则不保证)
final引用类型:写与引用不能重排序。注意溢出问题 构造函数 obj=this
多线程好处:减少上下文切换:无锁并发、CAS、最少线程、协程。
检查死锁 jstack -F pid
底层实现:
java代码--(编译)--》字节码--(加载)–》jvm–》cpu
实现依赖jvm和cup指令
volatile
cpu lock前缀指令:1、将处理器缓存写会内存。2、第一步操作导致其余缓存失效。
伪共享问题 缓存行为64字节 填充字节 1.8以后@Contend。
看缓存行大小 32字节 64字节,频繁写不适用。java7 重排序
synchronized markword 记录锁
普通对象:锁的是对象实例
静态对象:Class对象
方法: 方法内所有对象
实现:
jvm monitor对象
cpu:monitorenter 和monitorexit
monitorenter 同步代码块开始 monitorexit 同步代码快结束
每个对象都有一个monitor对象 当同步代码遇到对象时会获取对象的monitor对象。
1.6 从轻到重:无锁-偏向锁-轻量级锁-重量级锁 锁只能升级 为了提高获得释放的效率
偏向锁延迟-XX:BiasedLockingStartupDelayDelay=0
关闭偏向锁:-XX:UseBiasedLoking=false
轻量级锁:自旋锁竞争:不阻塞但消耗cpu, 释放轻量级锁如有竞争则升级为重量级锁
原子操作:
操作系统:1、总线锁 处理器占据总线锁 其余处理器阻塞。2、缓存锁:缓存到处理器内部 单缓存行
java:CAS 自旋CAS
存在问题:ABA:加版本号 1.5 Atomic包
循环时间长:pause指令、只能保证一个共享变量:多个共享变量变为一个共享变量。
线程通信:共享内存和消息传递
线程同步:按照一定顺序进行,共享内存是显示控制,消息传递是隐示控制
重排序:处理器会对单线程无依赖的读写操作做重排序。适当的位置插入内存屏障指令进行阻止。处理器只禁止影响结果的重排序 即使存在依赖关系 如 b=null b=set(b) String a=b 后2步可能重排序。
第二个操作位volatile写时或第一个操作位volatile读时, 不允许重排序
Happens-before
如果一个程序结果需要对另一个程序结果可见,则要保证happens-before
long和double 64位 不保证原子性。
锁的释放和获取与volatile的读写具有相同的内存语义。
ReentankLock实现依赖于AQS volatile的state变量
公平锁获取: state的读
非公平锁获取 是state的CAS
释放都是state的写。
courrent包实现:
共享变量设为 volatile ,然后CAS原子更新实现线程同步
final重排序规则
final基础类型:写不能排到构造函数之外。(保证别的线程引用该对象时,final变量已经被赋值,而非fianl则不保证)
final引用类型:写与引用不能重排序。注意溢出问题 构造函数 obj=this
双重检查锁:
当执行到第4步不为空时 仍会出现初始化不完整的情况。
1、加volatile即可。相当于第二步是volatile写 不允许重排序
2、静态内部类。初次加载就会被初始化。
线程状态:
new 初始 runnable 运行 blocked 阻塞 waiting 等待 timewaiting 超时等待
sleep方法会清除中断标识位。
volatile 线程获取变量必须从共享内存获取,更改变量必须刷回共享内存。
调用notify方法,wait不会立即返回,而是等到调用notify方法的方法结束。
降级锁: 获得写锁 再获得读锁 然后释放写锁。保证数据可见性
condation接口与lock锁配合实现等待/唤醒功能 condation.await 和signal
signal唤醒等待队列中等待时间最长的线程(首节点)
第二个操作位volatile写时或第一个操作位volatile读时, 不允许重排序
final基础类型:写不能排到构造函数之外。(保证别的线程引用该对象时,final变量已经被赋值,而非fianl则不保证)
final引用类型:写与引用不能重排序。注意溢出问题 构造函数 obj=this
多线程好处:减少上下文切换:无锁并发、CAS、最少线程、协程。
检查死锁 jstack -F pid
底层实现:
java代码--(编译)--》字节码--(加载)–》jvm–》cpu
实现依赖jvm和cup指令
volatile
cpu lock前缀指令:1、将处理器缓存写会内存。2、第一步操作导致其余缓存失效。
伪共享问题 缓存行为64字节 填充字节 1.8以后@Contend。
看缓存行大小 32字节 64字节,频繁写不适用。java7 重排序
synchronized markword 记录锁
普通对象:锁的是对象实例
静态对象:Class对象
方法: 方法内所有对象
实现:
jvm monitor对象
cpu:monitorenter 和monitorexit
monitorenter 同步代码块开始 monitorexit 同步代码快结束
每个对象都有一个monitor对象 当同步代码遇到对象时会获取对象的monitor对象。
1.6 从轻到重:无锁-偏向锁-轻量级锁-重量级锁 锁只能升级 为了提高获得释放的效率
偏向锁延迟-XX:BiasedLockingStartupDelayDelay=0
关闭偏向锁:-XX:UseBiasedLoking=false
轻量级锁:自旋锁竞争:不阻塞但消耗cpu, 释放轻量级锁如有竞争则升级为重量级锁
原子操作:
操作系统:1、总线锁 处理器占据总线锁 其余处理器阻塞。2、缓存锁:缓存到处理器内部 单缓存行
java:CAS 自旋CAS
存在问题:ABA:加版本号 1.5 Atomic包
循环时间长:pause指令、只能保证一个共享变量:多个共享变量变为一个共享变量。
线程通信:共享内存和消息传递
线程同步:按照一定顺序进行,共享内存是显示控制,消息传递是隐示控制
重排序:处理器会对单线程无依赖的读写操作做重排序。适当的位置插入内存屏障指令进行阻止。处理器只禁止影响结果的重排序 即使存在依赖关系 如 b=null b=set(b) String a=b 后2步可能重排序。
第二个操作位volatile写时或第一个操作位volatile读时, 不允许重排序
Happens-before
如果一个程序结果需要对另一个程序结果可见,则要保证happens-before
long和double 64位 不保证原子性。
锁的释放和获取与volatile的读写具有相同的内存语义。
ReentankLock实现依赖于AQS volatile的state变量
公平锁获取: state的读
非公平锁获取 是state的CAS
释放都是state的写。
courrent包实现:
共享变量设为 volatile ,然后CAS原子更新实现线程同步
final重排序规则
final基础类型:写不能排到构造函数之外。(保证别的线程引用该对象时,final变量已经被赋值,而非fianl则不保证)
final引用类型:写与引用不能重排序。注意溢出问题 构造函数 obj=this
双重检查锁:
当执行到第4步不为空时 仍会出现初始化不完整的情况。
1、加volatile即可。相当于第二步是volatile写 不允许重排序
2、静态内部类。初次加载就会被初始化。
线程状态:
new 初始 runnable 运行 blocked 阻塞 waiting 等待 timewaiting 超时等待
sleep方法会清除中断标识位。
volatile 线程获取变量必须从共享内存获取,更改变量必须刷回共享内存。
调用notify方法,wait不会立即返回,而是等到调用notify方法的方法结束。
降级锁: 获得写锁 再获得读锁 然后释放写锁。保证数据可见性
condation接口与lock锁配合实现等待/唤醒功能 condation.await 和signal
signal唤醒等待队列中等待时间最长的线程(首节点)
相关文章推荐
- 理解高并发(3).多线程开发常见问题示例
- 多线程状态的和守护线程的理解
- Python的多线程理解,转自虫师https://www.cnblogs.com/fnng/p/3670789.html
- C/C++杂记:深入理解数据成员指针、函数成员指针
- 对JAVA多线程 并发编程的理解
- 微冷的雨之Java中的多线程初理解(一)
- 【转载】C/C++杂记:深入理解数据成员指针、函数成员指针
- 对Java多线程在Netty中的应用的理解
- 对于多线程概念的理解
- 深入理解 Python 中的多线程 新手必看
- 多线程程序杂记
- 深入理解Java多线程中的wait(),notify()和sleep()
- Java多线程学习笔记——从Java JVM对多线程数据同步的一些理解
- 理解多线程并发
- 深入理解 Java 多线程核心知识:跳槽面试必备
- Java多线程 -- 深入理解JMM(Java内存模型) -- happens-before俗解
- java中多线程的基本理解以及运行机制
- ios 多线程的理解
- 谈谈多线程编程的个人理解(数据私有变量)
- Android下的多线程(Looper的理解)