@@ -280,7 +280,7 @@ MESI缓存一致性协议,通过对总线的侦听机制,很好地解决了
280
280
281
281
> 由于汇编代码比较长,虽然俺学了微机原理,但真的是看不懂😭。就挑最重要的一句摘录出来解释
282
282
283
-
283
+
284
284
285
285
``` java
286
286
0x0000000002c860bf :lock add dword ptr [rsp], Oh ; * putstatic initFlag
@@ -544,19 +544,49 @@ CPU为了提高执行效率,这三步操作的顺序可以是123,也可以
544
544
545
545
- sfence:即写屏障(Store Barrier),在写指令之后插入写屏障,能让写入缓存的最新数据写回到主内存,以保证写入的数据立刻对其他线程可见。
546
546
547
- - mfence,即全能屏障,具备ifence和sfence的能力。
547
+
548
548
549
549
- [ ] Lock前缀:Lock不是一种内存屏障,但是它能完成类似全能型内存屏障的功能。
550
550
551
551
` volatile ` 会给代码添加一个内存屏障,指令重排序的时候不会把后面的指令重排序到屏障的位置之前
552
552
553
553
![ ] ( https://iqqcode-blog.oss-cn-beijing.aliyuncs.com/img/20200613084031.png )
554
554
555
- > PS😐:只有一个CPU的时候,这种内存屏障是多余的。只有多个CPUI访问同一块内存的时候,就需要内存屏障了。
555
+ > PS😐:只有一个CPU的时候,这种内存屏障是多余的。只有多个CPU访问同一块内存的时候,就需要内存屏障了
556
+
557
+
558
+
559
+ ### 读写屏障
560
+
561
+ ** 写屏障** :保证 ` 屏障之前 ` 的代码** 不会** 进行重排序
562
+
563
+ ** 读屏障** :保证 ` 屏障之后 ` 的代码** 不会** 进行重排序
564
+
565
+ ``` java
566
+ static volatile boolean read;
567
+
568
+ public void actor1() {
569
+ num = 2 ;
570
+ ready = true ; // 写屏障
571
+ }
572
+
573
+ public void actor2() {
574
+ // 读屏障
575
+ if (ready) {
576
+ res = num + num;
577
+ } else {
578
+ res = 1 ;
579
+ }
580
+ }
581
+ ```
582
+
583
+ 通过读写屏障来保证内存之间的有序性,禁止指临重排。
584
+
585
+ <br >
556
586
557
587
### JMM的Happens-Before原则
558
588
559
- Happens-Before 是java内存模型中的语义规范,来阐述操作之间内存的可见性 ,可以确保一条语句的所有“写内存”操作对另一条语句是可见的。
589
+ Happens-Before 是java内存模型中的语义规范,来 ** 保证内存操作之间的可见性 ** ,可以确保一条语句的所有“写内存”操作对另一条语句是可见的。
560
590
561
591
** Happens-Before原则如下:**
562
592
@@ -568,13 +598,13 @@ Happens-Before 是java内存模型中的语义规范,来阐述操作之间内
568
598
569
599
4 . 传递规则:如果操作A先行发生于操作B,而操作B又先行发生于操作C,则可以得出操作A先行发生于操作C;
570
600
571
- 5 . 线程启动规则:Thread对象的start() 方法先行发生于此线程的每个一个动作;
601
+ 5 . 线程启动规则:Thread对象的 ` start() ` 方法先行发生于此线程的每个一个动作;
572
602
573
- 6 . 线程中断规则:对线程interrupt() 方法的调用先行发生于被中断线程的代码检测到中断事件的发生;
603
+ 6 . 线程中断规则:对线程 ` interrupt() ` 方法的调用先行发生于被中断线程的代码检测到中断事件的发生;
574
604
575
605
7 . 线程终结规则:线程中所有的操作都先行发生于线程的终止检测,我们可以通过Thread.join()方法结束、Thread.isAlive()的返回值手段检测到线程已经终止执行;
576
606
577
- 8 . 对象终结规则:一个对象的初始化完成先行发生于他的finalize() 方法的开始;
607
+ 8 . 对象终结规则:一个对象的初始化完成先行发生于他的 ` finalize() ` 方法的开始;
578
608
579
609
以上的happens-before原则为volatile关键字的可见性提供了强制保证。
580
610
0 commit comments