java——并发

一、并发(concurrent):多线程轮流使用cpu时间片。什么是时间片呢?操作系统层面上,在linux的内核处理过程中,每一个进程默认会有一个固定的时间片来执行命令(默认为10ms),window系统最小15ms

1) 单核cpu下,多线程并发实际由cpu时间片执行任务切换串行执行,此时的多线程并发,只是起到任务切换的作用(防止被单线程独占,别的任务加不进来)

          由于100ms以内是极短的、无法感知的时间。所以微观串行,宏观上这时也是并行(parallel)的。

 2) 对于多核cpu来说,多线程并发第一能够达到并行执行,提高效率(A计算20ms,B10ms,C15ms;串行是45ms,并行只需要20ms);

           第二能够起到异步调用(UI线程不必卡住等待耗时任务执行完成)

这就是并发。

 

二、CAS 实现原理

lock cmpxchg 汇编指令  (lock是几乎所有CPU都支持的一条汇编指令,指的是锁总线)

JDK提供的的轻量级线程安全操作(如自增等),它在无锁的状态下实现了线程安全。

1、juc里面都是cas实现,就是在用户态把问题解决了

2、CAS的第一个问题  ABA问题  版本号可以解决

3、CAS的第二个问题  compareAndSet修改值的那一段时间如果发生被篡改的问题,解决方法是 修改值的时候使用cas(lock cmpxchg)

 

三、Volitale实现原理

1、对象创建过程 

            (1)new <T>  堆上 m默认值0         

            (2)invoke special   m=8

            (3)astore  把t用指针指向堆内m=8地址  

也就是说,存在着对象被创建到一半,没有完成的时间段。

 

2、DCL单例需不需要volatile ?

需要。thread1半初始化的时候出现 (2)与(3)的指令乱序。导致thread2拿到了乱序后前的m=0的单例对象。

JVM 的规范,保证了volatile修饰的变量不能乱选。

如何做到的呢?JSR内存屏障 

                                          SSBarrier         LLBarrier 

   JVM层面(内存屏障)   Volaite写          Volaite读

                                          SLBarrier          LSBarrier

hotspot实现 lock addl 锁定一条空语句  在多cpu中执行指令时对内存独占使用,

它将当前cpu对应缓存内容刷到内存,并使其他cpu对应缓存失效,其他cpu只能重新去内存中读取

另外lock语句本身就是一把内存屏障,其他指令无法越过它。

3)volatile 禁止乱序执行的方法是使用lock addl的锁总线的方式来实现,它为什么不使用sfence等cpu原语呢

这是因为lock addl大多数cpu都支持,为了达到方便和普及的目的。

JVM规定八种情况必须加屏障  不能指令乱序 happens-before

as if serial 指令乱序对于单线程执行不会有问题

、Synchronized实现原理

lock cmpxchg 汇编指令 

所谓的锁对象 指的就是 把对象头中的锁信息标志(2字节)改为与之对应量级的锁

1、锁膨胀过程:

偏向锁——>轻量级(自旋锁)——> 

1)偏向锁指的是由于工程上70%的时候被synchronized修饰的变量只有单线程在跑,所以最开始的状态是偏向锁

2)锁竞争指的是偏向锁被JVM发现出现了第二个线程来访问

3)

 

 

2)markwork中另外有31位的hashcode以及gc标志信息

内存布局

markwork (8字节)

对象字节(4字节)

对齐padding

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值