当前位置: 首页 > news >正文

外贸网站建设服务平台企业网站建设一条龙多少钱

外贸网站建设服务平台,企业网站建设一条龙多少钱,网站设计工作室公司,中国2022年企业500强一览表目录 1. 基本概念 1.1、读屏障 (Load Barrier) 1.2、写屏障 (Store Barrier) 1.3、咖啡店例子 2. 常见内存屏障 2.1、volatile 1、缓存可见性 2、指令重排序 3、内存屏障 2.2、final 2.3、synchronized关键字 2.4、手动内存屏障 3、不同屏障类型对比 4、实…

目录

1. 基本概念

1.1、读屏障 (Load Barrier)

1.2、写屏障 (Store Barrier)

1.3、咖啡店例子

2. 常见内存屏障

2.1、volatile

1、缓存可见性

2、指令重排序

3、内存屏障

2.2、final

2.3、synchronized关键字        

2.4、手动内存屏障

3、不同屏障类型对比

4、实际CPU屏障指令

5、并发容器中的屏障应用

6、屏障对性能的影响


前言

        读屏障(Read Barrier)和写屏障(Write Barrier)是 Java 内存模型(JMM)中的重要概念,用于控制内存可见性和指令重排序。

   Memory Barrier,一种特殊的CPU指令,用于控制内存操作的顺序,确保指令的执行顺序和数据的可见性。

如下图所示:


1. 基本概念

        处理器为了提高性能,会对指令进行重排序,这在单线程环境下不会有问题,但在多线程环境下可能导致数据不一致的问题。内存屏障通过禁止指令重排序,确保多线程环境下的操作有序进行。

java对象的模型如下图所示:

具体如下:

        从主内存读取称为load,从本地内存修改往主内存称为store。

1.1、读屏障 (Load Barrier)

作用:确保在该屏障之后的读操作能看到屏障之前的所有写操作结果。

功能:刷新处理器缓存,使当前线程能看到其他线程的最新写入。

1.2、写屏障 (Store Barrier)

作用:确保在该屏障之前的写操作对其他处理器可见。

功能: 将写缓冲区的数据刷入主内存。

1.3、咖啡店例子

我用一个咖啡店的例子帮你理解内存屏障的概念,保证你看完就懂!

1. 基础概念类比

想象一个咖啡店的工作流程:

  • Store(写操作):就像咖啡师把做好的咖啡放在取餐台

  • Load(读操作):就像顾客从取餐台拿走咖啡

  • 内存屏障:就像店里的"请按顺序取餐"提示牌

2. 没有屏障的情况(问题场景)

咖啡店流程:

  1. 咖啡师A做美式咖啡(写操作:美式=1

  2. 咖啡师B做拿铁咖啡(写操作:拿铁=1

  3. 顾客看取餐台(读操作)

可能的问题
由于没有顺序保证,顾客可能看到:

  • 只有拿铁(美式还没放上来)

  • 只有美式(拿铁还没放上来)

  • 两者都看到(正确的顺序)

3. 加入写屏障(Store Barrier)

修改后的流程:

// 咖啡师工作流程(写操作)
void 制作饮品() {美式 = 1;          // 写操作1storeFence();     // 写屏障(相当于喊:"美式已做好!")拿铁 = 1;          // 写操作2
}

现在保证

  • 顾客要么看到"没有咖啡"

  • 要么看到"只有美式"

  • 要么看到"美式和拿铁都有"

但绝不会看到"只有拿铁"(因为写屏障确保美式先完成)

4. 加入读屏障(Load Barrier)

顾客查看流程(读操作):

void 查看饮品() {int 看到的拿铁 = 拿铁;  // 读操作1loadFence();          // 读屏障(相当于确认:"我看到的是最新数据")int 看到的美式 = 美式;  // 读操作2if (看到的拿铁 == 1) {System.out.println("美式状态:" + 看到的美式); }
}

现在保证
当顾客看到拿铁时,对美式的查看一定是最新值

5. 实际代码对应

class CoffeeShop {int 美式 = 0; // 0=没有,1=有int 拿铁 = 0;// 咖啡师制作(写操作)public void 制作饮品() {美式 = 1;Unsafe.getUnsafe().storeFence(); // 写屏障拿铁 = 1;}// 顾客查看(读操作)public void 查看饮品() {int 看到的拿铁 = 拿铁;Unsafe.getUnsafe().loadFence();  // 读屏障int 看到的美式 = 美式;if (看到的拿铁 == 1) {System.out.println("一定有美式:" + 看到的美式); // 因为写屏障保证美式先完成,读屏障保证看到最新值}}
}

6. 关键结论

  1. Store(写)屏障

    • 像喊"前面的写操作都完成了!"

    • 保证屏障前的写操作先于屏障后的写操作完成

  2. Load(读)屏障

    • 像喊"我要看最新数据!"

    • 保证屏障后的读操作能看到屏障前所有写操作的结果

  3. 为什么需要

    • 没有屏障时,CPU/编译器可能重排序指令

    • 就像咖啡师可能为了效率调整制作顺序

小结:

        现在你应该能明白:内存屏障就像咖啡店里的"顺序提示牌",确保制作(Store)和取餐(Load)按照预期的顺序进行!

2. 常见内存屏障

2.1、volatile

更多volatile的介绍可参考:对于Synchronized和Volatile的深入理解_线程的volatile和synchronize-CSDN博客

        volatile是Java中用来处理内存可见性问题的一种机制。被声明为volatile的变量会在每次读写时都强制刷新到主内存,并从主内存加载最新的值,从而避免了缓存一致性问题。

1、缓存可见性

关于volatile的数据结构原理,如下所示:

2、指令重排序

3、内存屏障

内存屏障模型如下图所示:


代码示例如下:

class VolatileExample {private volatile boolean flag = false;private int value = 0;public void writer() {value = 42;          // 普通写flag = true;         // volatile写(隐含写屏障)}public void reader() {if (flag) {          // volatile读(隐含读屏障)System.out.println(value); // 保证能看到value=42}}
}

屏障分析

  1. flag = true 之前插入写屏障

    • 确保 value = 42 先于 flag = true 对其他线程可见

  2. if (flag) 之后插入读屏障

    • 确保读取 value 时能获取最新值。

2.2、final

class FinalExample {final int x;int y;public FinalExample() {x = 42;  // final写y = 50;  // 普通写}public void reader() {if (y == 50) {System.out.println(x); // 保证看到x=42}}
}

屏障分析

  • final字段写入后会有写屏障,确保构造器结束前final字段对其他线程可见

2.3、synchronized关键字        

关于更多synchronized的介绍可参考:对于Synchronized和Volatile的深入理解_线程的volatile和synchronize-CSDN博客

        synchronized不仅可以用来实现互斥锁,还可以用来实现内存可见性。进入和退出synchronized块时,会自动插入内存屏障,确保变量的可见性。


        synchronized在进入临界区时会插入一个load barrier,在退出临界区时会插入一个store barrier。

代码示例:

public class SynchronizedExample {private boolean flag = false;public void writer() {synchronized (this) {flag = true;// JVM会在这里插入一个store barrier}}public void reader() {synchronized (this) {if (flag) {System.out.println("Flag is true!");// JVM会在这里插入一个load barrier}}}
}

        在这个例子中,writer方法和reader方法都被synchronized修饰,确保了writer线程对flag的修改能够被reader线程及时看到。

        在JVM中,进入和退出synchronized块时,会调用monitorenter和monitorexit指令。这两个指令会插入必要的内存屏障,确保内存的可见性。

2.4、手动内存屏障

Java 通过 Unsafe 类提供手动屏障控制(Java 9+ 使用 VarHandle):

import sun.misc.Unsafe;class ManualBarrierExample {private int x;private int y;private static final Unsafe unsafe = Unsafe.getUnsafe();public void write() {x = 1;// 手动插入写屏障unsafe.storeFence();y = 2;}public void read() {int localY = y;// 手动插入读屏障unsafe.loadFence();int localX = x;System.out.println("x=" + localX + ", y=" + localY);}
}
  1. 使用 Unsafe 类在实际项目中是不推荐的,因为它:

    • 是内部API,可能在不同JDK版本中变化

    • 直接操作内存,容易导致JVM崩溃

    • 通常有更好的替代方案(如 VarHandle

VarHandle.fullFence();  // 替代 Unsafe 的全屏障
VarHandle.acquireFence(); // 读屏障
VarHandle.releaseFence(); // 写屏障


3、不同屏障类型对比

关于不同屏障类型可参考如下:

具体的作用范围可参考:


4、实际CPU屏障指令

不同架构的实现:

  • x86: mfence (全屏障), lfence (读屏障), sfence (写屏障)

  • ARM: dmb (数据内存屏障)

  • PowerPC: sync


5、并发容器中的屏障应用

ConcurrentHashMap 中的示例:

final V putVal(K key, V value) {// ...tab[index] = new Node<K,V>(hash, key, value, null); // 普通写// 隐式的StoreStore屏障synchronized (this) { // 确保节点插入先于桶的链表指针更新}// ...
}

6、屏障对性能的影响

测试数据(纳秒/操作):

最佳实践

  1. 尽量使用volatile:比手动屏障更安全高效

  2. 减少屏障使用:只在必要时插入

  3. 了解硬件特性:x86的TSO模型已经提供较强一致性

  4. 屏障组合使用:如双重检查锁定模式中的用法

        理解这些屏障机制可以帮助开发者编写出正确且高效的多线程程序。它通过禁止指令重排序和确保变量的可见性,保障了多线程环境下的数据一致性。


参考文章:

1、什么是内存屏障?-CSDN博客

http://www.dtcms.com/a/445427.html

相关文章:

  • 平台网站做等级保护测评成都网站营销seo多少费用
  • 电脑系统下载官方网站怎样推广公司的网站
  • 营销网站建设情况调查问卷京东网站建设策划书
  • 网站建设 网站优化营销型网站建设专家英文网站制作公司哪家好
  • 大英做网站仙桃网站优化
  • 无锡网站建设优化网站定制开发流程
  • 网站建设维护专员岗位说明网站备案安全责任书是谁盖章
  • 玄武营销型网站制作厂家兼职网站推广如何做
  • 浏览器显示不安全网站建设网站织梦用字体矢量图做图标
  • 建筑设计网站app小程序api开发
  • 一起作业网站英语作业怎么做哈尔滨网站建设团队
  • 做网站赚钱 2017网站建设售前说明书
  • 网站鼠标悬停动态效果代码濉溪县最新通告今天
  • 建设网站制作项目描述做网站和做app哪个难
  • 四川省住房与建设厅网站用二级域名做网站对seo
  • 巢湖路桥建设集团网站婚恋网站哪家做的最好
  • 做网站买服务器怎么样汉字域名网站
  • 搜狐最大的门户网站如何撰写网站建设方案书
  • 公司搭建网站服务网络工程师培训班在哪里
  • 珠海网站建设 骏域网站wordpress html伪静态
  • 福州网站建设印秀微商怎样让客源主动加你
  • 设计好的制作网站安庆建设银行网站
  • 上传照片的网站赚钱数字化校园建设网站
  • 商城网站开发需求100个农村电商平台
  • 地方农村电商平台网站设计思路做特卖的网站爱库存
  • 做茶歇的网站东莞市网络营销公司
  • 网站建设开发心得2023年电商平台排行榜
  • 做网站公司找意向客户qq云 wordpress
  • 健网站怎么做企业网站建设的现状
  • 钓鱼网站怎么制作html站点搜索