多线程与高并发的一些知识总结

Posted scanner小霸王

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程与高并发的一些知识总结相关的知识,希望对你有一定的参考价值。

1.CAS(比较和交换compareAndSwap):

概念(无锁)
1)读取当前值E,计算结果V,比较E与新值N是否一样;
2)一样的话就证明这个过程没有发生改变,直接修改值为V;
3)否则,将值置为N(被其他线程改变后的值),重复1),2)步骤

2.64位虚拟机,8个字节(意思就是能被8整除,对齐部分就是为了补齐字节后被 8整除的)

new 一个对象T{int m =8;} new T();
会开辟一个空间
主要四个部分:
(markword 8个字节
(压缩后4个字节,a,存在锁的信息;b.gc标记信息;c.hashCode),
klass pointer(记录属于哪个.class文件),
变量 int m 4个字节,padding (对齐))

3.用户态和内核态区别

内核态(Kernel Mode):运行操作系统程序,操作硬件
用户态(User Mode):运行用户程序

4.锁的升级

1)
a).new 的时候若偏向锁未启动 普通对象
b) new的时候若偏向锁启动 直接 偏向锁状态
无锁态(00000001)–>
偏向锁(00000101)
(只要有另外一个线程来争,就会升级为轻量级锁)
–>轻量级锁/自旋锁 无锁(00000000)(自旋《即循环,需要占用cpu资源》超过10次或者线程总数超过总核数的1/2)
–>重量级锁(00000010)

偏向锁:当前线程的指针指向markword
(没有抢占资源,存在的原因:多数sychronized方法,很多情况只有一个线程在运行)
轻量级锁:(需要抢锁,看谁能把标签贴到markword上去,不需要经过操作系统内核的)
重量级锁:(需要向操作系统申请)
2)轻量级别锁vs重量级锁
a)轻量锁执行时间短,适用与线程多,时间短的
b)重量锁不需要cpu资源,将线程扔进等待队列,轮到你了,才叫醒

在这里插入图片描述
c)
偏向锁,自旋锁都是用户空间完成的
重量级锁是需要内核申请的

5.volatile的作用

1)线程可见性
java中,堆内存是线程共享的,而每个线程都有字节独享的内存用于工作。所以,当线程访问到堆内存中的共享变量时候,会copy一份到自己的工作空间。之后在对空间中的值进行操作,完成后再重新写回堆内存。
所以,当有多个线程同时访问这个变量的时候,可能无法拿到实时的值。
可见性的原理:
MESI(缓存一致性)协议:
a).写数据时候,发现是共享变量,会发出信号通知其他CPU设置改变量的缓存行为无效状态
b).当其他CPU使用这个变量的时候,会失去观察是否有更改的信号,当发现缓存行失效时候,会从主内存(堆中)重新读取此变量。
优点:高效(非锁机制)
缺点:仅仅保证可见性,不保证数据一致性。
参考博客:https://www.cnblogs.com/nysd/p/12547703.html

2)防止指令重排序
new 一个对象(创建一个对象,初始化,建立关联)
DCL单例锁的双重判断
a)怎么实现:JSR内存屏障
b)不管如何重排序,单线程执行结果不会改变

6.缓存行:

当我们从主存里面读数据的时候,是按照一行或者一块来着(一行64个字节)
缓存行越大,局部性空间效率越大,但读取时间慢;
缓存行越小,局部性空间效率越低,但读取的时间快

1)伪共享,缓存行失效
那么为什么会出现伪共享问题呢?上诉的情况再扩展一下,假设在多线程情况下,x,y两个共享变量在同一个缓存行中,核a修改变量x,会导致核b,核c中的x变量和y变量同时失效。
此时对于在核a上运行的线程,仅仅只是修改了了变量x,却导致同一个缓存行中的所有变量都无效,需要重新刷缓存

以上是关于多线程与高并发的一些知识总结的主要内容,如果未能解决你的问题,请参考以下文章

多线程与高并发线程安全

并发编程知识点总结

Java并发编程与高并发解决方案

Java 多线程知识的简单总结

java多线程高并发知识总结

python并发编程知识点总结