多线程的volatile关键字
1、volatile作用 轻量级的synchronized,保证多处理器开发中的共享变量的可见性,如果这个变量修饰符使用恰当的话,不会引起上下文的切换和调度。 2、执行流程 volatile进行写操作时,会多出一行汇编代码,即lock前缀指令 该指令在多核处理器中: 引起处理器缓存写到内存 Lock#信号会锁定访问的内存区域的缓存,并且写入到内存,使用缓存一致性来确保修改的一致性,此操作成为缓存锁定。锁总线开销较大,所有锁缓存。缓存一致性会阻止同时修改由两个以上处理器缓存的内存区域数据。 一个处理器的缓存回写到内存会导致其他处理器的缓存无效。 使用MESI控制协议去维护内部缓存和其他处理器缓存的一致性。处理器使用嗅探技术保证内部缓存、系统内存和其他处理器的缓存的数据在总线上保持一致,如果使用嗅探技术检测其他处理器打算写内存地址,则在下次访问相同内存地址时,强制执行缓存行填充 3、使用优化 使用队列集合类Linked-TransferQuene,使用volatile变量时,采用追加方式优化队列出队和入队的性能。 追加到64字节是因为大部分处理器L1,2,3的高速缓存行时64个字节带宽,不支持部分填充缓存行,当队列头结点和尾结点都不足64字节,处理器会将其读入一个高速缓存行,将整个缓存行锁定,在缓存一致性的作用下,导致其他处理器不能访问自己的高速缓存行的尾结点,入队和出队需要不断修改头尾结点,严重影响效率。如果追加64字节方式填满高速缓存行,避免头尾结点加载到同一缓存行,则头尾结点不会在修改时互相锁定。 追加场景: 缓存行非64字节宽的处理器 共享变量不会被频繁写,追加方式需要处理器读取更多字节到高速缓存区,具有一定性能消耗,如果共享变量不会频繁被写,锁的几率很小,则没必要追加方式避免相互锁定。Java7后可能不生效。