java并发艺术 散装笔记

2021-03-23  本文已影响0人  圆企鹅i

《JAVA并发编程的艺术》 方腾飞,魏鹏,程晓明 -- 笔记

1.避开死锁

1.1 避免一个线程获取多个锁
1.1 避免一个锁在锁内同时占用多个资源
1.1 尝试使用定时锁
1.1 对于数据库锁,加锁和解锁在一个数据库链接里。

2.资源限制

2.1网络限制

带宽固定

2.2线程限制
2.3资源竞争限制

3.底层实现

3.1 volatile

volatile 修饰变量 让所有线程看到的变量是一致的

3.1.1 模型
image.png

会发现每个CPU(每条线程)都是在拿自己的数据在玩
所以在并发的情况下,有可能所有cpu都把原数据10进行+1,然后内存中数据被写了三次11

image.png image.png

这说明,在某些场景,轻量级的volatile 比synchronize更加简单的高效

3.1.2 实现指令
  1. LOCK指令

A .该汇编指令,会锁住CPU的缓存(近年的cpu 之前是锁主线程)
如果该缓存里面有对应内存的数据--->LOCK#指令 会将缓存回写到内存中 同时启用缓存锁定,阻止其他缓存修改

B. 处理器的嗅探技术,正在写数据的CPU将会使用嗅探到其他CPU也有该内存数据的缓存,并使其缓存无效

注意:CPU不直接和内存进行交互,而是缓存到L1/2/3级CPU缓存当中

3.2 volatile的字节补充优化

Douglea
JDK1.7 JAVA并发包中的队列集合 Linkded-TransferQueue队列
使用追加字节来优化缓存行的问题

image.png

P6系列和奔腾系列CPU缓存行32字节,其余64字节
队列里的头尾节点,因为经常操作的原因,必然面临多次写操作
如果队列里的数据字节过少,volatile使用的缓存锁定功能必然锁定头尾两个数据。
多线程同时处理头尾数据,则变成另一个CPU无法去修改头尾中的另一个,理想的并行变成串行。
所以,Douglea在头尾的两个对象,进行字节补充,补充到64位,则不会互相锁住,达到并行。

不过这种方式在Java7中可能不生效,它还设计了更加智慧的追加字节的方式。

上一篇下一篇

猜你喜欢

热点阅读