synchronized&volatile

用户态与内核态

早期的synchronized是重量级锁,申请锁通过kernel来申请,系统调用,用户空间-》内核空间,代价太大

CAS:自旋锁

怎么解决CAS的ABA问题?加version、布尔值、时间戳都可以

Automic类用的是CAS,底层通过指令cmpxchg来实现,但是这个指令不是原子性的,需要指令lock_if_mp来保证原子性(如果mp就lock)mp:multi processor 多处理器 lock:锁定总线(cpu去内存访问值的时候锁定总线)

JOL:java object layout 

升级过程:图 主线 

偏向锁:将线程ID放到对象的markword里,并不调用操作系统

自旋锁:线程修改markword的ID,谁修改成功,谁持有

重量级锁:太多线程自旋,竞争激烈,消耗资源太多,直接使用重量级锁,所有自旋的线程进waitSet等待队列,不再自旋

什么时候升级成重量级锁:1.6之前线程自旋10次或自旋线程超过cpu总核1/2,之后:自适应自旋,根据每个线程的情况决定升不升重量级锁,我理解是比较自旋还是切换内核态占用资源多

关于java -xx:多是涉及jvm调优的

为什么BiasedBlocking偏向锁延迟时间是4秒钟,jvm启动完之后隔4s再来开启偏向锁,如果这个时间之内有竞争锁,就不启用偏向锁了,直接启用轻量级锁,效率反而更高

锁重入,一个方法调用另一个方法,两个方法中都有对某个对象的加锁

重量级锁底层实现:ObjectMonitor,AQS

 

 

volatile:

  线程间可见;java工作模型,线程(cpu)从内存中读取数据到自己的缓存,不加volatile的话不会去读主存数据;通过缓存一致性协议实现。cpu每次会读64个字节,所以可能会产生读的一块数据内有两个数据都有volatile,效率慢,解决方法:缓存行对其

  禁止指令重排:指令重排乱序

 

对象创建过程

DCL:double check lock  dcl必须加volatile,可能会造成拿到半初始化的数据,在百万并发的情况下,有百万分之一的情况概率

volatile的底层是内存屏障,在jvm和cpu级别是完全不一样的概念

posted @ 2020-06-21 22:51  nlw  阅读(156)  评论(0编辑  收藏  举报