关于并发的一些思考

1 锁

  悲观锁和乐观锁
  jdk1.6之后对锁进行了优化:偏向锁、轻量锁、自旋锁、重量锁,jvm在获取锁的时候,逐级增加锁定程度。

1.1 锁的方式

  • sychronized:原生锁,jvm实现。
  • ReentrantLock:java.util.concurrent包下API层面的锁。通过lock()和unlock()锁定和释放锁。提供了一些高级功能:等待可中断、公平锁(构造器中参数为true,性能较差)、锁绑定多个条件

  sychronized和ReentrantLock在1.6以后,性能相差不大,官方推荐使用sychronized。

2 缓存行

  计算机cpu和主内存间还要一级缓存(单个cpu私有)、二级缓存(单个cpu私有)、三级缓存(多核共有),每一级缓存间的性能都几倍甚至十几倍的差距,而缓存和内存达到近百倍。
  缓存被分成N组,每一组又有N行个缓存行(最小的存储单位,每次从内存中加载一个缓存行的数据)组成,每一个cache Line通常有个64字节(由系统决定)来存储数据。每个Cache Line又额外包含一个有效位(valid bit)、t个标记位(tag bit),其中valid bit用来表示该缓存行是否有效;tag bit用来协助寻址,唯一标识存储在CacheLine中的块;而Cache Line里的64个字节其实是对应内存地址中的数据拷贝。
  一个缓存行可以存储8个long类型的数据。缓存行加载时会额外加载相邻的7个数据,因此你可以非常快速的遍历在连续的内存块中分配的任意数据结构。当缓存行中有一个数据被修改时,该缓存行失效。多线程存在写的行为时,会对其他读或写的线程产生影响,无法有效利用缓存,只能从新冲主内存中读取。
  伪共享:当多线程修改互相独立的变量时,如果这些变量共享同一个缓存行,就会无意中影响彼此的性能,这就是伪共享。
在这里插入图片描述
  在核心1上运行的线程想更新变量X,同时核心2上的线程想要更新变量Y。不幸的是,这两个变量在同一个缓存行中。每个线程都要去竞争缓存行的所有权来更新变量。如果核心1获得了所有权,缓存子系统将会使核心2中对应的缓存行失效。当核心2获得了所有权然后执行更新操作,核心1就要使自己对应的缓存行失效。这会来来回回的经过L3缓存,大大影响了性能。如果互相竞争的核心位于不同的插槽,就要额外横跨插槽连接,问题可能更加严重。

3 java内存布局和内存屏障

  对于HotSpot来说,默认策略是longs/doubles、ints、shorts/chars,bytes/booleans、oops(Ordinary Object Pointers),相同宽度的字段被分配到一起。父类变量默认在子类之前。可以通过设置占位变量实现缓冲行填充,来把对象的属性隔离到不同的缓存行上。jdk1.8缓存行填充注解:@Contended
  内存屏障:它是一个CPU指令,插入一个内存屏障,相当于告诉CPU和编译器先于这个命令的必须先执行,后于这个命令的必须后执行。使用关键字volatile的属性,Java内存模型将在写操作后插入一个写屏障指令,在读操作前插入一个读屏障指令。

2 并发框架

2.1 Disruptor

  disruptor提供了一种线程之间信息交换的方式。
  Ring Buffer它是一个环,是一个数组类型的结构(数组内元素的内存地址的连续性存储的),可以把它用做在不同上下文(线程)间传递数据的buffer。基本来说,ringbuffer拥有一个序号,这个序号指向数组中下一个可用的元素。
  每个消费者知道自己将要处理的序号,然后调用ConsumerBarrier从RingBuffer总读取数据。不需要加锁,也不需要用另外的队列来协调不同的线程(消费者)。
  生产者会自旋等待所有的消费者离开RingBuffer游标的下一个节点,然后抢占这个节点,并把下一个序号更新为当前节点的序号。第二步,只有在 Ring Buffer 游标到达准备提交的节点的前一个节点时它才会提交(解决多个生产者写入数据的情况,多个生产者可以并发获取到后面各自可用的节点和序号),更新游标并通知ConsumerBarrier 上的 WaitStrategy 对象。
  在整个过程中,既没有锁,也没有内存屏障。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值