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

简述电子商务网站开发的基本原则wordpress访客量

简述电子商务网站开发的基本原则,wordpress访客量,计算机网站开发实现总结,keep的营销策略分析转载自 永远爱大家的 程序员小灰 ————— 第二天 ————— ———————————— Java内存模型简称JMM#xff08;Java Memory Model#xff09;#xff0c;是Java虚拟机所定义的一种抽象规范#xff0c;用来屏蔽不同硬件和操作系统的内存访问差异#xff0c;让j…转载自 永远爱大家的 程序员小灰 ————— 第二天 ————— ———————————— Java内存模型简称JMMJava Memory Model是Java虚拟机所定义的一种抽象规范用来屏蔽不同硬件和操作系统的内存访问差异让java程序在各种平台下都能达到一致的内存访问效果。 Java内存模型长成什么样子呢就是下图的样子 这里需要解释几个概念 1.主内存Main Memory 主内存可以简单理解为计算机当中的内存但又不完全等同。主内存被所有的线程所共享对于一个共享变量比如静态变量或是堆内存中的实例来说主内存当中存储了它的“本尊”。 2.工作内存Working Memory 工作内存可以简单理解为计算机当中的CPU高速缓存但又不完全等同。每一个线程拥有自己的工作内存对于一个共享变量来说工作内存当中存储了它的“副本”。 线程对共享变量的所有操作都必须在工作内存进行不能直接读写主内存中的变量。不同线程之间也无法访问彼此的工作内存变量值的传递只能通过主内存来进行。 以上说的这些可能有点抽象大家来看看下面这个例子 对于一个静态变量 static int s 0 线程A执行如下代码 s 3 那么JMM的工作流程如下图所示 通过一系列内存读写的操作指令JVM内存模型共定义了8种内存操作指令以后会细讲线程A把静态变量 s0 从主内存读到工作内存再把 s3 的更新结果同步到主内存当中。从单线程的角度来看这个过程没有任何问题。 这时候我们引入线程B执行如下代码 System.out.println(s s); 引入线程B以后当线程A首先执行更大的可能是出现下面情况 此时线程B从主内存得到的s值是3理所当然输出 s3这种情况不难理解。但是有较小的几率出现另一种情况 因为工作内存所更新的变量并不会立即同步到主内存所以虽然线程A在工作内存当中已经把变量s的值更新成3但是线程B从主内存得到的变量s的值仍然是0从而输出 s0。 volatile关键字具有许多特性其中最重要的特性就是保证了用volatile修饰的变量对所有线程的可见性。 这里的可见性是什么意思呢当一个线程修改了变量的值新的值会立刻同步到主内存当中。而其他线程读取这个变量的时候也会从主内存中拉取最新的变量值。 为什么volatile关键字可以有这样的特性这得益于java语言的先行发生原则happens-before。先行发生原则在维基百科上的定义如下 In computer science, the happened-before relation is a relation between the result of two events, such that if one event should happen before another event, the result must reflect that, even if those events are in reality executed out of order (usually to optimize program flow). 翻译结果如下 在计算机科学中先行发生原则是两个事件的结果之间的关系如果一个事件发生在另一个事件之前结果必须反映即使这些事件实际上是乱序执行的通常是优化程序流程。 这里所谓的事件实际上就是各种指令操作比如读操作、写操作、初始化操作、锁操作等等。 先行发生原则作用于很多场景下包括同步锁、线程启动、线程终止、volatile。我们这里只列举出volatile相关的规则 对于一个volatile变量的写操作先行发生于后面对这个变量的读操作。 回到上述的代码例子如果在静态变量s之前加上volatile修饰符 volatile static int s 0 线程A执行如下代码 s 3 这时候我们引入线程B执行如下代码 System.out.println(s s); 当线程A先执行的时候把s 3写入主内存的事件必定会先于读取s的事件。所以线程B的输出一定是s 3。 这段代码是什么意思呢很简单开启10个线程每个线程当中让静态变量count自增100次。执行之后会发现最终count的结果值未必是1000有可能小于1000。 使用volatile修饰的变量为什么并发自增的时候会出现这样的问题呢这是因为count这一行代码本身并不是原子性操作在字节码层面可以拆分成如下指令 getstatic //读取静态变量count iconst_1 //定义常量1 iadd //count增加1 putstatic //把count结果同步到主内存 虽然每一次执行 getstatic 的时候获取到的都是主内存的最新变量值但是进行iadd的时候由于并不是原子性操作其他线程在这过程中很可能让count自增了很多次。这样一来本线程所计算更新的是一个陈旧的count值自然无法做到线程安全 因此什么时候适合用volatile呢 1.运行结果并不依赖变量的当前值或者能够确保只有单一的线程修改变量的值。 2.变量不需要与其他的状态变量共同参与不变约束。 第一条很好理解就是上面的代码例子。第二条是什么意思呢可以看看下面这个场景 volatile static int start 3; volatile static int end 6; 线程A执行如下代码 while (start end){ //do something } 线程B执行如下代码 start3; end3; 这种情况下一旦在线程A的循环中执行了线程Bstart有可能先更新成6造成了一瞬间 start end从而跳出while循环的可能性。 什么是指令重排 指令重排是指JVM在编译Java代码的时候或者CPU在执行JVM字节码的时候对现有的指令顺序进行重新排序。 指令重排的目的是为了在不改变程序执行结果的前提下优化程序的运行效率。需要注意的是这里所说的不改变执行结果指的是不改变单线程下的程序执行结果。 然而指令重排是一把双刃剑虽然优化了程序的执行效率但是在某些情况下会影响到多线程的执行结果。我们来看看下面的例子 在线程B中执行: while( ! contextReady ){ sleep(200); } doAfterContextReady (context); 以上程序看似没有问题。线程B循环等待上下文context的加载一旦context加载完成contextReady true的时候才执行doAfterContextReady 方法。 但是如果线程A执行的代码发生了指令重排初始化和contextReady的赋值交换了顺序 在线程B中执行: while( ! contextReady ){ sleep(200); } doAfterContextReady (context); 这个时候很可能context对象还没有加载完成变量contextReady 已经为true线程B直接跳出了循环等待开始执行doAfterContextReady 方法结果自然会出现错误。 需要注意的是这里java代码的重排只是为了简单示意真正的指令重排是在字节码指令的层面。 什么是内存屏障 内存屏障Memory Barrier是一种CPU指令维基百科给出了如下定义 A memory barrier, also known as a membar, memory fence or fence instruction, is a type of barrier instruction that causes a CPU or compiler to enforce an ordering constraint on memory operations issued before and after the barrier instruction. This typically means that operations issued prior to the barrier are guaranteed to be performed before operations issued after the barrier. 翻译结果如下 内存屏障也称为内存栅栏或栅栏指令是一种屏障指令它使CPU或编译器对屏障指令之前和之后发出的内存操作执行一个排序约束。 这通常意味着在屏障之前发布的操作被保证在屏障之后发布的操作之前执行。 内存屏障共分为四种类型 LoadLoad屏障 抽象场景Load1; LoadLoad; Load2 Load1 和 Load2 代表两条读取指令。在Load2要读取的数据被访问前保证Load1要读取的数据被读取完毕。 StoreStore屏障 抽象场景Store1; StoreStore; Store2 Store1 和 Store2代表两条写入指令。在Store2写入执行前保证Store1的写入操作对其它处理器可见 LoadStore屏障 抽象场景Load1; LoadStore; Store2 在Store2被写入前保证Load1要读取的数据被读取完毕。 StoreLoad屏障 抽象场景Store1; StoreLoad; Load2 在Load2读取操作执行前保证Store1的写入对所有处理器可见。StoreLoad屏障的开销是四种屏障中最大的。 volatile做了什么 在一个变量被volatile修饰后JVM会为我们做两件事 1.在每个volatile写操作前插入StoreStore屏障在写操作后插入StoreLoad屏障。 2.在每个volatile读操作前插入LoadLoad屏障在读操作后插入LoadStore屏障。 或许这样说有些抽象我们看一看刚才线程A代码的例子 我们给contextReady 增加volatile修饰符会带来什么效果呢 context loadContext() 和屏障下方的volatile写入语句 contextReady true 无法交换顺序从而成功阻止了指令重排序。 volatile特性之一 保证变量在线程之间的可见性。可见性的保证是基于CPU的内存屏障指令被JSR-133抽象为happens-before原则。 volatile特性之二 阻止编译时和运行时的指令重排。编译时JVM编译器遵循内存屏障的约束运行时依靠CPU屏障指令来阻止重排。 几点补充 1. 关于volatile的介绍本文很多内容来自《深入理解Java虚拟机》这本书。有兴趣的同学可以去看看。 2. 在使用volatile引入内存屏障的时候普通读、普通写、volatile读、volatile写会排列组合出许多不同的场景。我们这里只简单列出了其中一种有兴趣的同学可以查资料进一步学习其他阻止指令重排的场景。 3.volatile除了保证可见性和阻止指令重排还解决了long类型和double类型数据的8字节赋值问题。这个特性相对简单本文就不详细描述了。 4.本漫画纯属娱乐还请大家尽量珍惜当下的工作切勿模仿小灰的行为哦。 —————END—————
http://www.pierceye.com/news/222386/

相关文章:

  • 西安电子商务网站建设网站里面的链接怎么做
  • 郑州陆港开发建设有限公司网站58招商加盟项目
  • 徐州高端网站建设个人网站设计首页界面
  • 山西企业建站系统平台关键词 优化 网站
  • 地板网站建设方案有什么做美食的网站
  • 网站建设丶金手指专业网站幻灯片 字段
  • 网站开发技术总结干完房产中介整个人废了
  • iis建站安装wordpress对网站建设的评价语
  • 网站开发网站建设公司二手房网
  • 72建站网如何建设一个药材网站做网站的费用 可以抵扣吗
  • 四川通信建设工程有限公司网站做企业网站需要服务器么
  • 福田建网站费用烟台招远网站建设
  • 上海网站开发建设电话丹东市做网站
  • 外贸网站 免费模板 使用 zencart做新闻类网站
  • 呼和浩特网站推广大德通网站建设
  • 携程旅行网站建设上海城市建设大学网站
  • 360网站收录做网站设计用什么软件
  • 微信html5模板网站最新网站建设软件有哪些
  • 芝麻开门网站建设无极电影网怎样下载电影
  • 网站开发 书籍首页关键词优化价格
  • 网站建设建站流程方案百度一下你就知道下载安装
  • 大型网站快速排名学生做的网站能攻击
  • 怎样做加入购物车的网站wordpress SQL 配置
  • 网站设计原型品牌建设人才队伍建设
  • 常熟网站网站建设电商购物平台软件开发
  • 网站页尾信息网站建设费用摊销年限
  • 制作个人网站要多少钱重庆工程信息官网
  • 那里建设网站好珠海网站建设公司哪个好
  • 从化市营销型网站建设工业和信息化部五系网站建设
  • 网站建设的开发方法有哪些wordpress 企业站主题