JAVA 高并发多线程学习笔记
Java并发及高并发
一:cpu多级缓存
1:为什么要使用多集缓存
cpu的处理速度比主存的速度快太多了,cpu大多数情况都是在等待主存的io,为了减少cpu的等待时间,所以加入缓存;
2:如何工作
当cpu要用到主存中的数据进行计算时,先将主存中的数据刷新到缓存,cpu与缓存的数据进行交换,当cpu计算完成,会重新刷入到缓存中,然后再从缓存刷入到主存中;
3:这样反而是麻烦了,真的有必要吗
从空间的角度,一个文件此时被访问,那么在不久后被重新访问的概率也一定高于没被访问的
从时间的角度,一个文件此时被访问,那在他附近的文件也有可能会被访问
4:缓存一致性,MESI协议
M:被修改的 可信,与主存中的数据一致
E:独享的 可信,与主存中的数据一致
S:共享的 不可信
I:失效的 不可信
二:java内存模型
1:什么是java内存模型
java内存模型是jvm虚拟出来的物理内存,分为堆跟栈,堆中一般放java对象,栈中放java对象的引用,判断一个对象是否可以被访问,那就看栈中有没有指向堆,如果两个线程栈都有指向相同的堆,分别copy一份私有的成员变量,这个时候就有数据一致性的问题;
2:java内存模型跟计算机的硬件有什么关联
计算机中的硬件,cpu,cpu寄存器,缓存,主存 是没有堆栈之分的,每个里面都有堆栈
三:同步的八种操作
lock:加锁,同一资源只能有一个线程被加锁,但是一个线程可以被添加多次,反之也是需要解锁多次;
read:读取数据
load:加载
used:使用
assign:分配
store:
write:回写
unlock:解锁
四:并发的好处以及劣势
1:好处
速度:同时处理多个请求,响应更快
设计:
资源利用:cpu能够在等待io的时候多做一些事情
2:坏处
安全行:多个线程访问共享数据
活跃性:某歌操作无法继续下去,死锁,饥饿
性能:多个线程切换来回切换,消耗内存
五:并发的基础概念
线程池,信号量,countDownLatch
六:原子性-Atomic包- 互斥操作,只可以有一个线程进行操作
1:Cas的概念,比较与交换
AtomicInt 可以使的线程安全
2:AtomicLong 跟 LongAdder 的区别
AtomicLong 是死循环,
LongAddr 优先选择,因为在高并发的计算下,LongAddr会将数据分配数组中,当线程过来访问时,通过hash等算法获取到数组中的值进行计算,热点数据value会被分成多个单元的sele,每个sale独自维护自己的数据,最后累计求和,这样一来可以有效的提高并行度;防止单点压力,提高性能,但是在高并发更新的时候会有问题,会造成数据不一致,如果要求数据唯一,那还是选择AtomicLong
底层使用 unsafe.compareAndSwapInt方法
使用do while 方法,无限循环比较,当前的值跟底层查出来的值是否相等,如果相等则更新,不想等则在从count中取出当前值进行计算
3:atomicReference ,atomicintReferenceFileUpdater
atomicReference.compareAndSet(0,1);
当 atomicReference 等于0时,更新为1
4:AtomicStampReference:解决CAS的ABA问题
多线程情况下,一个线程对一个参数进行了 +1又-1点操作,另外一个线程进来操作此数据默认时没人操作过,这是不符合设计理念的,
所以使用 stamp进行控制,每次操作都会有个version进行+1,当第一个线程+1-1后,stamp为3
七:原子性- 锁
1:synchronized 一来JVM
同步锁,修饰四种类型
修饰代码块:大括号括起来的代码,作用于调用的对象
修饰方法:整个方法,作用于调用的对象
修饰静态方法:整个静态方法,作用于 所有对象
修饰类:括号括起来的部分,作用于所有对象
2:synchronized跟lock的对比
synchronized:不可中断锁,适合竞争不激烈,可读性好
lock:可中断锁,多样化同步,竞争激烈是仍能维持常态
atomic:竞争激烈时也能维持常态,比lock性能好;只能同步一个值
八:可见性,synchronized,volatile 一个线程的操作会对另外线程的可视化
导致不可见的原因
1:线程交叉执行
2:冲排序结合线程交叉执行
3:共享变量更新后的值没有
JMM关于对synchronized的两条规定
线程解锁前,必须把共享变量的最新值刷新到主内存中
线程加锁时,将清空工作内存中共享变量的值,从而使用共享变量时需要从主内存中重新读区最新的值
可见性 - volatile,wo轮特u
1:对volatile变量操作时,会在写操作后加入一条store屏蔽指令,将本地内存中的共享变量刷新到主内存
2:对volatile变量读操作时,会在读操作前加入一条load屏蔽指令,从主内存中读取共享变量
九:有序性,happens-before
保证有序性,防止重排序
十:发布对象