SEO教程

SEO教程

Products

当前位置:首页 > SEO教程 >

中国建设银行在哪些招聘网站发布招聘信息?

96SEO 2026-02-19 09:47 13


结果一个线程依赖于另一个线程互斥一个资源只能一个线程使用分工计算很大数据量的时候大任务拆分成小任务然后进行结果合并

中国建设银行在哪些招聘网站发布招聘信息?

让一个线程修改的共享变量立刻刷回主内存使这个共享变量在其他CPU的本地内存失效

并行和并发

并行:指在同一时刻有多条指令在多个处理器上同时执行。

所以无论是从微观还是从宏观来看二者都是一起执行的。

并发指在同一时刻只能有一条指令执行但多个进程指令被快速的轮换执行使得在宏观上具有多个进程同时执行的效果但在微观上并不是同时执行的只是把时间分成若干段使多个进程快速交替的执行。

并行在多处理器系统中存在而并发可以在单处理器和多处理器中都存在并发能够在单处理器中存在是因为并发是并行的家乡并行要求程序能够同时执行多个操作而并发只是要求程序假装同时执行多个操作每个小时间片执行一个操作多个操作快速切换执行

并发三大特性

当一个线程修改了共享变量的值其他线程能够看到修改的值。

Java内存模型是通过在变量修改后将新值同步回主内存在变量读取前从主内存刷新变量值这种依赖主内存作为传递媒介的方法来实现可见性的

通过volatile关键字保证可见性通过内存屏障保证可见性通过synchronized关键字保证可见性通过Lock保证可见性通过final关键字保证可见性

有序性

即程序执行的顺序按照代码的先后顺序执行。

JVM存在指令重排所以存在有序性问题。

如何保证有序性

通过volatile关键字保证有序性通过内存屏障来保证有序性通过synchronized关键字保证有序性通过Lock保证有序性

原子性

一个或多个操作要么全部执行且在执行过程中不被任何因素打断要么全部不执行。

在Java中对基本数据类型的变量的读取和赋值操作是原子性操作64位处理器。

不采取如何原子性保证措施的自增操作并不是原子性的。

如何保证原子性

通过synchronized关键字保证原子性通过Lock保证原子性通过CAS保证原子性

在32位的机器上对long类型变量进行加减操作是否存在并发隐患

在32位的Java虚拟机上对long类型变量的读写操作不是原子性的因为long类型需要64位而32位的JVM一次只能操作32位。

这意味着对long类型变量的读写会被分解为两个32位操作这两个操作可能会被其他线程的操作打断从而导致并发问题

https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html

出于Java编程语言内存模型的目的对非易失性长值或双精度值的一次写操作被视为两次单独的写操作:对每个32位一半进行一次写操作。

这可能导致这样一种情况即线程从一次写入中看到64位值的前32位而从另一次写入中看到第二个32位。

volatile

对引用的写入和读取始终是原子的无论它们是作为32位值还是64位值实现的。

一些实现可能会发现将对64位长值或双精度值的单个写操作划分为对相邻32位值的两个写操作是很方便的。

为了提高效率此行为是特定于实现的;Java虚拟机的实现可以自由地自动或分两部分执行对长值和双精度值的写操作。

鼓励Java虚拟机的实现尽可能避免拆分64位值。

鼓励程序员将共享的64位值声明为易失性或正确同步他们的程序以避免可能出现的复杂性。

public

false;System.out.println(Thread.currentThread().getName()

修改flag:

{System.out.println(Thread.currentThread().getName()

开始执行......);while

LockSupport.unpark(Thread.currentThread());}System.out.println(Thread.currentThread().getName()

跳出循环:

让ThreadA执行一会儿Thread.sleep(1000);//

线程threadB通过flag控制threadA的执行时间Thread

threadB

threadB);threadB.start();Thread.sleep(1000);}

}Java内存模型JMM

Java虚拟机规范中定义了Java内存模型用于屏蔽掉各种硬件和操作系统的内存访问差异以实现让Java程序在各种平台下都能达到一致的并发效果JMM规范了Java虚拟机玉计算机内存是如何协同工作的:规定了一个线程如何和何时可以看到有其他线程修改过后的共享变量的值以及在必须时如何同步的访问共享变量。

JMM描述的是一种抽象的概念一组规则通过这组规则控制程序中各个变量在共享数据区域和私有数据区域的访问方式JMM是围绕原子性、有序性、可见性展开的

Java内存模型与硬件架构之间存在差异。

硬件内存架构没有区分线程栈和堆对于硬件所有的线程栈和堆都分布在主内存中。

部分线程栈和堆可能有时候会出现在CPU缓存中和CPU内部的寄存器中。

如下图所示Java内存模型和计算机硬件内存架构是一个交叉关系

内存交互操作

关于主内存与工作内存之间的具体交互协议即一个变量如何从主内存拷贝到工作内存如何从工作内存同步到主内存之间的实现细节Java内存模型定义了以下八种操作来完成

Lock锁定作用于主内存的变量把一个变量标识位一条线程独占状态

unLock解锁作用于主内存变量把一个处于锁定状态的变量释放出来释放后的变量才可以被其它线程锁定

read读取作用域主内存变量把一个变量值从主内存传输到线程的工作内存中以便随后的load动作使用

load载入作用于工作内存的变量它把read操作从主内存中得到的变量值放入工作内存的变量副本中

use使用作用于工作内存的变量把工作内存中的一个变量值传递给执行引擎每当虚拟机遇到一个需要使用变量的值的字节码指令时将会执行这个操作。

assign赋值作用于工作内存的变量它把一个从执行引擎收到的值赋值给工作内存的变量每当虚拟机遇到一个给变量赋值的字节码指令时执行这个操作。

store存储作用于工作内存的变量把工作内存中的一个变量的值传送到主内存中以便随后的write操作

write写入作用于主内存的变量它把store操作从工作内存中一个变量的值传送到主内存的变量中

Java内存模型还规定了在执行上述八种基本操作时必须满足如下规则

如果要把一个变量从主内存复制到工作内存就需要按顺序地指定read和load操作如果把变量从工作内存同步回主内存中就需要按顺序地执行store和write操作。

但Java内存模型只要求上述步骤必须按顺序执行而没有保证必须是连续执行。

不允许read和load、store和write操作之一单独出现

不允许一个线程丢弃它的最近assign的操作即变量在工作内存中改变了之后必须要同步到主内存中。

不允许一个线程无原因地没有发生任何assign操作把数据从工作内存同步回主内存中

一个新的变量只能在主内存中诞生不允许在工作内存中直接使用一个未被初始化load或assign的变量。

即对一个变量实施use和store操作之前必须先执行过了assign和load操作。

一个变量在同一时刻只允许一条线程对其进行lock操作但lock操作可以被同一条线程重复执行多次多次执行lock后只有执行相同次数的unlock操作变量才会被解锁。

lock和unlock必须成对出现。

如果一个变量执行lock操作将会清空工作内存中此变量的值在执行引擎中使用这个变量前需要重新执行load或assign操作初始化变量的值

如果一个变量事先没有被lock操作锁定则不允许它执行unlock操作也不允许去unlock一个被其他线程锁定的变量

对一个变量执行unlock操作之前那必须先把此变脸沟通不到主内存中执行store和write操作

单线程程序。

单线程程序不会出现内存可见性问题。

编译器、runtime和处理器会共同确保单线程程序的执行结果于该程序在顺序一致性模型中的执行结果相同。

正确同步的多线程程序。

正确同步的多线程程序的执行将具有顺序一致性程序的执行结果与该程序在顺序一致性内存模型中的执行结果相同。

这是JMM关注的重点JMM通过现在编译器和处理器的重排序和处理器的重排序来为程序员提供内存可见性保证。

未同步/未正确同步的多线程程序。

JMM为他们提供了最小安全性保障线程执行读取到的值要么是之前某个线程写入的值要么是默认值未同步程序在JMM中的执行时整体上是无序的其执行结果无法预知。

JMM不保证位同步程序的执行结果与该程序在顺序一致性模型中的执行结果一致

未同步程序在JMM中执行时整体是无序的其执行结果无法预知。

未同步程序在两个模型中的执行特性有如下几个差异

顺序一致性模型保证单线程内的操作会按程序的顺序执行而JMM不保证单线程内的操作会按程序的顺序执行比如正确同步的多线程程序在临界区内的重排序

顺序一致性模型保证所有的线程只能看到一致的操作执行顺序而JMM不保证所有线程能看到一致的操作执行顺序。

顺序一致性模型保证对所有内存读/写操作都具有原子性而JMM不保证对64位的long型和double型变量的写操作具有原子性32位处理器

JVM在32位处理器上运行时可能会把一个64位long/double型变量的写操作拆分为两个32位的写操作来执行。

这两个32位的写操作可能会被分配到不同的总线事务中执行此时对这个64位变量的写操作将不具有原子性。

从JSR-133内存模型开始即从JDK5开始仅仅只允许把一个64位long/double型变量的写操作拆分为两个32位的写操作来执行任意的读操作在JSR-133中都必须具有原子性

可见性对一个volatile变量的读总是能看到任意线程对这个volatile变量最后的写入原子性对任意单个volatile变量的读/写具有原子性但类似于volatile这中复合操作不具有原子性基于这点我们通常会认为volatile不具备原子性。

volatile仅仅保证对单个volatile变量的读/写具有原子性而锁的互斥执行的特性可以确保对整个临界代码的执行具有原子性。

64位的long型和double型变量只要它是volatile变量对该变量的读/写就具有原子性。

有序性:对volatile修饰的变量的读写操作前后加上各种内存屏障来禁止指令重排序来保证有序性

在JSR-133之前的旧Java内存模型中虽然不允许volatile变量之间重排序但旧的Java内存模型允许volatile变量与普通变量重排序。

为了提供一种比锁更轻量级的线程之间通信的机制JSR-133专家组决定增强volatile的内存语义严格限制编译器和处理器对volatile变量与普通变量的重排序确保volatile的写-读和锁的释放-获取具有相同的内存语义。

当写一个volatile变量时JMM会把该线程对应的本地内存中的共享变量值刷新到主内存当读一个volatile变量时JMM会把该线程对应的本地内存置为无效线程接下来将从主内存中读取共享变量。

JMM内存交互层面实现

volatile修饰的变量read、load、use操作和assign、store、write必须是连续的即修改后必须立即同步会主内存使用时必须从主内存刷新由此保存volatile变量操作对多线程的可见性。

硬件层面实现

通过lock前缀指令会锁定变量缓存行区域并写回主内存这个操作称为“缓存锁定”缓存一致性机制回阻止同时修改两个以上处理器缓存的内存取区域数据。

一个处理器的缓存回写到内存回导致其他处理器的缓存无效。

字节码解释器实现

JVM中的字节码解释器bytecodeInterpreter用C实现了JVM指令其优点是实现相对简单容易理解缺点是执行慢

模板解释器实现

模板解释器(templateInterpreter)其对每个指令都写了一段对应的汇编代码启动时将每个指令与对应汇编代码入口绑定可以说是效率做到了极致。

void

TemplateTable::volatile_barrier(Assembler::Membar_mask_bitsorder_constraint)

{//

TemplateTable::putfield_or_static(int

byte_no,

notVolatile);putfield_or_static_helper(byte_no,

is_static,

flags);volatile_barrier(Assembler::Membar_mask_bits(Assembler::StoreLoad

jmp(Done);__

bind(notVolatile);putfield_or_static_helper(byte_no,

is_static,

orderAccess_linux_x86.inline.hpp

inline

#endif}x86处理器中利用lock实现类似内存屏障的效果。

确保后续指令执行的原子性。

在Pentium及之前的处理器中带有lock前缀的指令在执行期间会锁住总线使得其它处理器暂时无法通过总线访问内存很显然这个开销很大。

在新的处理器中Intel使用缓存锁定来保证指令执行的原子性缓存锁定将大大降低lock前缀指令的执行开销。

Lock前缀指令具有类似内存屏障的功能禁止该指令与前面和后面的读写指令重排序。

Lock前缀指令回等待它之前所有的指令完成并且所有的缓冲的写操作写回内存也就是将store

buffer中的内容写入内存之后才开始执行并且根据缓存一致性协议刷新store

-XX:PrintAssembly

《64-ia-32-architectures-software-developer-vol-3a-part-1-manual.pdf》中有如下描述

The

32位的IA-32处理器支持对系统内存中的位置进行锁定的原子操作。

这些操作通常用于管理共享的数据结构(如信号量、段描述符、系统段或页表)在这些结构中两个或多个处理器可能同时试图修改相同的字段或标志。

处理器使用三种相互依赖的机制来执行锁定的原子操作:

有保证的原子操作总线锁定使用LOCK#信号和LOCK指令前缀缓存一致性协议确保原子操作可以在缓存的数据结构上执行(缓存锁);这种机制出现在Pentium

4、Intel

https://note.youdao.com/ynoteshare/index.html?idfbe82b30b77ce9180b48c7440781bb08typenote_time1708180884391

有序性问题深入分析

a;}});thread1.start();thread2.start();thread1.join();thread2.join();System.out.println(第

));if

Java语言规范规定JVM线程内部维持顺序化语义。

即只要程序的最终结果与它顺序化情况的结果相等那么指令的执行顺序可以与代码顺序不一致此过程叫指令的重排序。

指令重排序的意义JVM能根据处理器特性CPU多级缓存系统、多核处理器等适当的对机器指令进行重排序使机器指令更能符合CPU的执行特性最大限度的发挥机器性能。

volatile禁止重排序场景

第二个操作是volatile写不管第一个操作是什么都不会重排序第一个操作是volatile读不管第二个操作是什么都不会重排序第一个操作是volatile写第二个操作是volatile读也不会发生重排序。

JMM内存屏障插入策略

在每个volatile写操作的前面插入一个StoreStore屏障在每个volatile写操作的后面插入一个StoreLoad屏障在每个volatile读操作的后面插入一个LoadLoad屏障在每个volatile读操作的后面插入一个LoadStore屏障

会省略掉这3种操作类型对应的内存屏障。

仅会对写-读操作做重排序所以volatile写-读操作只需要在volatile写后插入StoreLoad屏障

LoadLoad屏障指令Load1;

Load2在Load2及后续读取操作要读取的数据被访问前保证Load1要读取的数据被读取完毕。

LoadStore屏障指令Load1;

LoadStore;

Store2在Store2及后续写入操作被刷出前保证Load1要读取的数据被读取完毕。

StoreStore屏障指令Store1;

StoreStore;

Store2在Store2及后续写入操作执行前保证Store1的写入操作对其它处理器可见StoreLoad屏障指令Store1;

StoreLoad;

Load2在Load2及后续所有读取操作执行前保证Store1的写入对所有处理器可见。

它的开销是四种屏障中最大的。

在大多数处理器的实现中这个屏障是个万能屏障兼具其它三种内存屏障的功能

由于x86只有store

load可能会重排序所以只有JSR的StoreLoad屏障对应它的mfence或lock前缀指令其他屏障对应空操作

硬件层内存屏障

fence(Intel的提法)来提供一致性的能力。

拿X86平台来说有几种主要的内存屏障

Barrier

是一种全能型的屏障具备lfence和sfence的能力Lock前缀Lock不是一种内存屏障但是它能完成类似内存屏障的功能。

Lock会对CPU总线和高速缓存加锁可以理解为CPU指令级的一种锁。

它后面可以跟ADD,

ADC,

Barrier来说在读指令前插入读屏障可以让高速缓存中的数据失效重新从主内存加载数据对Store

Barrier来说在写指令之后插入写屏障能让写入缓存的最新数据写回到主内存。

Lock前缀实现了类似的能力它先对总线和缓存加锁然后执行后面的指令最后释放锁后会把高速缓存中的数据刷新回主内存。

在Lock锁住总线的时候其他CPU的读写请求都会被阻塞直到锁释放。

不同硬件实现内存屏障的方式不同Java内存模型屏蔽了这种底层硬件平台的差异由JVM来为不同的平台生成相应的机器码。

Java并发知识脑图

https://www.processon.com/view/link/615d4a610e3e74663e97fa0e

as-if-serial

as-if-serial语义的意思不管怎么重排序编译器为了提高并发度单线程程序的执行结果不能被改变。

编译器、runtime和处理器都必须遵守as-if-serial语义

为了遵守as-if-serial语义编译器和处理器不会对存在数据依赖关系的操作做重排序因为这种重排序会改变执行结果。

但是如果操作之间不存在数据依赖关系这些操作就可能被编译器和处理器重排序。

double

CA和C之间存在数据依赖关系同时B和C之间也存在数据依赖关系。

因此在最终执行的指令序列中C不能被重排序到A和B的前面C排到A和B的前面程序的结果将会被改变。

但A和B之间没有数据依赖关系编译器和处理器可以重排序A和B之间的执行顺序。

happens-before

开始JMM使用happens-before的概念来阐述多线程之间的内存可见性。

在JMM中如果一个操作执行的结果需要对另一个操作可见那么这两个操作之间必须存在happens-before关系。

happens-before原则非常重要它是判断数据是否存在竞争、线程是否安全的主要依据依靠这个原则我们解决在并发环境下两操作之间是否可能存在冲突的所有问题。

下面我们就一个简单的例子稍微了解下happens-before

//线程A执行

如果一个操作happens-before另一个操作那么第一个操作的执行结果将对第二个操作可见而且第一个操作的执行顺序排在第二个操作之前。

两个操作之间存在happens-before关系并不意味着一定要按照happens-before原则制定的顺序来执行。

如果重排序之后的执行结果与按照happens-before关系来执行的结果一致那么这种重排序并不非法。

程序次序规则一个线程内按照代码顺序书写在前面的操作先行发生于书写在后面的操作锁定规则一个unLock操作先行发生于后面对同一个锁的lock操作volatile变量规则对一个变量的写操作先行发生于后面对这个变量的读操作传递规则如果操作A先行发生于操作B而操作B又先行发生于操作C则可以得出操作A先行发生于操作C.线程启动规则Thread对象的start()方法先行发生于此线程的每个一个动作线程中断规则对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生线程终结规则线程中所有的操作都先行发生于线程的终止检测我们可以通过Thread.join()方法结束、Thread.isAlive()的返回值手段检测到线程已经终止执行对象终结规则一个对象的初始化完成先行发生于他的finalize()方法的开始

程序次序规则一段代码在单线程中执行的结果是有序的。

注意是执行结果因为虚拟机、处理器会对指令进行重排序。

虽然重排序了但是并不会影响程序的执行结果所以程序最终执行的结果与顺序执行的结果是一致的。

故而这个规则只对单线程有效在多线程环境下无法保证正确性。

锁定规则这个规则比较好理解无论是在单线程环境还是多线程环境一个锁处于被锁定状态那么必须先执行unlock操作后面才能进行lock操作。

volatile变量规则这是一条比较重要的规则它标志着volatile保证了线程可见性。

通俗点讲就是如果一个线程先去写一个volatile变量然后一个线程去读这个变量那么这个写操作一定是happens-before读操作的。

happens-before

线程启动规则假定线程A在执行过程中通过执行ThreadB.start()来启动线程B那么线程A对共享变量的修改在接下来线程B开始执行后确保对线程B可见。

线程终结规则假定线程A在执行的过程中通过制定ThreadB.join()等待线程B终止那么线程B在终止之前对共享变量的修改在线程A等待返回后可见。

上面八条是原生Java满足Happens-before关系的规则但是我们可以对他们进行推导出其他满足happens-before的规则

1.将一个元素放入一个线程安全的队列的操作Happens-Before从队列中取出这个元素的操作

2.将一个元素放入一个线程安全容器的操作Happens-Before从容器中取出这个元素的操作

3.在CountDownLatch上的倒数操作Happens-Before

4.释放Semaphore许可的操作Happens-Before获得许可操作

5.Future表示的任务的所有操作Happens-Before

Future#get()操作

6.向Executor提交一个Runnable或Callable的操作Happens-Before任务开始执行操作

如果两个操作不存在上述前面8条

后面6条任一一个happens-before规则那么这两个操作就没有顺序的保障JVM可以对这两个操作进行重排序。

如果操作A

happens-before操作B那么操作A在内存上所做的操作对操作B都是可见的。

private

}我们约定线程A执行write()线程B执行read()且线程A优先于线程B执行那么线程B获得结果是什么我们就这段简单的代码一次分析happens-before的规则规则5、6、7、8

由于两个方法是由不同的线程调用所以肯定不满足程序次序规则两个方法都没有使用锁所以不满足锁定规则变量i不是用volatile修饰的所以volatile变量规则不满足传递规则肯定不满足

happens-before线程B虽然可以确认在时间上线程A优先于线程B指定但是就是无法确认线程B获得的结果是什么所以这段代码不是线程安全的。

那么怎么修复这段代码呢满足规则2、3任一即可。

happens-before原则是JMM中非常重要的原则它是判断数据是否存在竞争、线程是否安全的主要依据保证了多线程环境下的可见性。

CPU缓存架构缓存一致性协议详解

CPU缓存即高速缓冲存储器是位于CPU与主内存间的一种容量较小但速度很高的存储器。

由于CPU的速度远高于主内存CPU直接从内存中存取数据要等待一定时间周期Cache中保存着CPU刚用过或循环使用的一部分数据当CPU再次使用该部分数据时可从Cache中直接调用,减少CPU的等待时间提高了系统的效率。

在CPU访问存储设备时无论是存取数据抑或存取指令都趋于聚集在一片连续的区域中这就是局部性原理。

时间局部性Temporal

Locality如果一个信息项正在被访问那么在近期它很可能还会被再次访问。

空间局部性Spatial

Locality如果一个存储器的位置被引用那么将来他附近的位置也会被引用。

多CPU多核缓存架构

**物理CPU**物理CPU就是插在主机上的真实的CPU硬件在Linux下可以数不同的physical

核心数我们常常会听说多核处理器其中的核指的就是核心数。

在Linux下可以通过cores来确认主机的物理CPU的核心数。

逻辑CPU逻辑CPU跟超线程技术有联系假如物理CPU不支持超线程的那么逻辑CPU的数量等于核心数的数量如果物理CPU支持超线程那么逻辑CPU的数目是核心数数目的两倍。

在Linux下可以通过

processors

现代CPU为了提升执行效率减少CPU与内存的交互一般在CPU上集成了多级缓存架构常见的为三级缓存结构。

缓存一致性Cache

计算机体系结构中缓存一致性是共享资源数据的一致性这些数据最终存储在多个本地缓存中。

当系统中的客户机维护公共内存资源的缓存时可能会出现数据不一致的问题这在多处理系统中的cpu中尤其如此。

在共享内存多处理器系统中每个处理器都有一个单独的缓存内存共享数据可能有多个副本:一个副本在主内存中一个副本在请求它的每个处理器的本地缓存中。

当数据的一个副本发生更改时其他副本必须反映该更改。

缓存一致性是确保共享操作数(数据)值的变化能够及时地在整个系统中传播的规程。

**写传播**Write

对任何缓存中的数据的更改都必须传播到对等缓存中的其他副本(该缓存行的副本)。

**事务串行化**Transaction

对单个内存位置的读/写必须被所有处理器以相同的顺序看到。

理论上一致性可以在加载/存储粒度上执行。

然而在实践中它通常在缓存块的粒度上执行。

**一致性机制**Coherence

请求/转发/响应)但使用更少的带宽因为消息是点对点的而不是广播的。

由于这个原因许多较大的系统(64处理器)使用这种类型的缓存一致性。

总线仲裁机制

在计算机中数据通过总线在处理器和内存之间传递。

每次处理器和内存之间的数据传递都是通过一系列步骤来完成的这一系列步骤称之为总线事务Bus

Transaction和写事务WriteTransaction。

读事务从内存传送数据到处理器写事务从处理器传送数据到内存每个事务会读/写内存中一个或多个物理上连续的字。

这里的关键是总线会同步试图并发使用总线的事务。

在一个处理器执行总线事务期间总线会禁止其他的处理器和I/O设备执行内存的读/写。

Arbitration会对竞争做出裁决这里假设总线在仲裁后判定处理器A在竞争中获胜总线仲裁会确保所有处理器都能公平的访问内存。

此时处理器A继续它的总线事务而其他两个处理器则要等待处理器A的总线事务完成后才能再次执行内存访问。

假设在处理器A执行总线事务期间不管这个总线事务是读事务还是写事务处理器D向总线发起了总线事务此时处理器D的请求会被总线禁止。

总线的这种工作机制可以把所有处理器对内存的访问以串行化的方式来执行。

在任意时间点最多只能有一个处理器可以访问内存。

这个特性确保了单个总线事务之中的内存读/写操作具有原子性。

原子操作是指不可被中断的一个或者一组操作。

处理器会自动保证基本的内存操作的原子性也就是一个处理器从内存中读取或者写入一个字节时其他处理器是不能访问这个字节的内存地址。

最新的处理器能自动保证单处理器对同一个缓存行里进行16/32/64位的操作是原子的但是复杂的内存操作处理器是不能自动保证其原子性的比如跨总线宽度、跨多个缓存行和跨页表的访问。

处理器提供总线锁定和缓存锁定两个机制来保证复杂内存操作的原子性。

总线锁定

LOCK信号当其中一个处理器在总线上输出此信号时其它处理器的请求将被阻塞住那么该处理器可以独占共享内存

缓存锁定

由于总线锁定阻止了被阻塞处理器和所有内存之间的通信而输出LOCK#信号的CPU可能只需要锁住特定的一块内存区域因此总线锁定开销较大。

缓存锁定是指内存区域如果被缓存在处理器的缓存行中并且在Lock操作期间被锁定那么当它执行锁操作回写到内存时处理器不会在总线上声言LOCK信号总线锁定信号而是修改内部的内存地址并允许它的缓存一致性机制来保证操作的原子性因为缓存一致性机制会阻止同时修改由两个以上处理器缓存的内存区域数据当其他处理器回写已被锁定的缓存行的数据时会使缓存行无效。

当操作的数据不能被缓存在处理器内部或操作的数据跨多个缓存行时则处理器会调用总线锁定。

有些处理器不支持缓存锁定。

《64-ia-32-architectures-software-developer-vol-3a-part-1-manual.pdf》中有如下描述

The

32位的IA-32处理器支持对系统内存中的位置进行锁定的原子操作。

这些操作通常用于管理共享的数据结构(如信号量、段描述符、系统段或页表)在这些结构中两个或多个处理器可能同时试图修改相同的字段或标志。

处理器使用三种相互依赖的机制来执行锁定的原子操作:

有保证的原子操作总线锁定使用LOCK#信号和LOCK指令前缀缓存一致性协议确保原子操作可以在缓存的数据结构上执行(缓存锁);这种机制出现在Pentium

4、Intel

cache)监视或窥探总线事务的一种方案其目标是在分布式共享内存系统中维护缓存一致性。

包含一致性控制器(snooper)的缓存称为snoopy缓存。

该方案由Ravishankar和Goodman于1983年提出。

工作原理

当特定数据被多个缓存共享时处理器修改了共享数据的值更改必须传播到所有其他具有该数据副本的缓存中。

这种更改传播可以防止系统违反缓存一致性。

数据变更的通知可以通过总线窥探来完成。

所有的窥探者都在监视总线上的每一个事务。

如果一个修改共享缓存块的事务出现在总线上所有的窥探者都会检查他们的缓存是否有共享块的相同副本。

如果缓存中有共享块的副本则相应的窥探者执行一个动作以确保缓存一致性。

这个动作可以是刷新缓存块或使缓存块失效。

它还涉及到缓存块状态的改变这取决于缓存一致性协议cache

coherence

当处理器写入一个共享缓存块时其他缓存中的所有共享副本都会通过总线窥探失效。

这种方法确保处理器只能读写一个数据的一个副本。

其他缓存中的所有其他副本都无效。

这是最常用的窥探协议。

MSI、MESI、MOSI、MOESI和MESIF协议属于该类型。

Write-update

当处理器写入一个共享缓存块时其他缓存的所有共享副本都会通过总线窥探更新。

这个方法将写数据广播到总线上的所有缓存中。

它比write-invalidate协议引起更大的总线流量。

这就是为什么这种方法不常见。

Dragon和firefly协议属于此类别。

一致性协议Coherence

一致性协议在多处理器系统中应用于高速缓存一致性。

为了保持一致性人们设计了各种模型和协议如MSI、MESI(又名Illinois)、MOSI、MOESI、MERSI、MESIF、write-once、Synapse、Berkeley、Firefly和Dragon协议。

MSI

MESI协议是一个基于写失效的缓存一致性协议是支持回写write-back缓存的最常用协议。

也称作伊利诺伊协议

(Illinois

protocol因为是在伊利诺伊大学厄巴纳-香槟分校被发明的)。

与写通过write

through缓存相比回写缓冲能节约大量带宽。

总是有“脏”dirty状态表示缓存中的数据与主存中不同。

MESI协议要求在缓存不命中miss且数据块在另一个缓存时允许缓存到缓存的数据复制。

与MSI协议相比MESI协议减少了主存的事务数量。

这极大改善了性能。

已修改Modified

缓存行是脏的dirty与主存的值不同。

如果别的CPU内核要读主存这块数据该缓存行必须回写到主存状态变为共享(S).

独占Exclusive

缓存行只在当前缓存中但是干净的–缓存数据同于主存数据。

当别的缓存读取它时状态变为共享当前写数据时变为已修改状态。

共享Shared

缓存行也存在于其它缓存中且是未修改的。

缓存行可以在任意时刻抛弃。

无效Invalid

如果多个核的线程在操作同一个缓存行中的不同变量数据那么就会出现频繁的缓存失效即使在代码层面看这两个线程操作的数据之间完全没有关系。

这种不合理的资源竞争情况就是伪共享False

linux下查看Cache

注意需要配置jvm参数-XX:-RestrictContended

public

System.currentTimeMillis();Thread

new

{pointer.y;}});t1.start();t2.start();t1.join();t2.join();System.out.println(pointer.x,pointer.y);System.out.println(System.currentTimeMillis()

start);}



SEO优化服务概述

作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。

百度官方合作伙伴 白帽SEO技术 数据驱动优化 效果长期稳定

SEO优化核心服务

网站技术SEO

  • 网站结构优化 - 提升网站爬虫可访问性
  • 页面速度优化 - 缩短加载时间,提高用户体验
  • 移动端适配 - 确保移动设备友好性
  • HTTPS安全协议 - 提升网站安全性与信任度
  • 结构化数据标记 - 增强搜索结果显示效果

内容优化服务

  • 关键词研究与布局 - 精准定位目标关键词
  • 高质量内容创作 - 原创、专业、有价值的内容
  • Meta标签优化 - 提升点击率和相关性
  • 内容更新策略 - 保持网站内容新鲜度
  • 多媒体内容优化 - 图片、视频SEO优化

外链建设策略

  • 高质量外链获取 - 权威网站链接建设
  • 品牌提及监控 - 追踪品牌在线曝光
  • 行业目录提交 - 提升网站基础权威
  • 社交媒体整合 - 增强内容传播力
  • 链接质量分析 - 避免低质量链接风险

SEO服务方案对比

服务项目 基础套餐 标准套餐 高级定制
关键词优化数量 10-20个核心词 30-50个核心词+长尾词 80-150个全方位覆盖
内容优化 基础页面优化 全站内容优化+每月5篇原创 个性化内容策略+每月15篇原创
技术SEO 基本技术检查 全面技术优化+移动适配 深度技术重构+性能优化
外链建设 每月5-10条 每月20-30条高质量外链 每月50+条多渠道外链
数据报告 月度基础报告 双周详细报告+分析 每周深度报告+策略调整
效果保障 3-6个月见效 2-4个月见效 1-3个月快速见效

SEO优化实施流程

我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:

1

网站诊断分析

全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。

2

关键词策略制定

基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。

3

技术优化实施

解决网站技术问题,优化网站结构,提升页面速度和移动端体验。

4

内容优化建设

创作高质量原创内容,优化现有页面,建立内容更新机制。

5

外链建设推广

获取高质量外部链接,建立品牌在线影响力,提升网站权威度。

6

数据监控调整

持续监控排名、流量和转化数据,根据效果调整优化策略。

SEO优化常见问题

SEO优化一般需要多长时间才能看到效果?
SEO是一个渐进的过程,通常需要3-6个月才能看到明显效果。具体时间取决于网站现状、竞争程度和优化强度。我们的标准套餐一般在2-4个月内开始显现效果,高级定制方案可能在1-3个月内就能看到初步成果。
你们使用白帽SEO技术还是黑帽技术?
我们始终坚持使用白帽SEO技术,遵循搜索引擎的官方指南。我们的优化策略注重长期效果和可持续性,绝不使用任何可能导致网站被惩罚的违规手段。作为百度官方合作伙伴,我们承诺提供安全、合规的SEO服务。
SEO优化后效果能持续多久?
通过我们的白帽SEO策略获得的排名和流量具有长期稳定性。一旦网站达到理想排名,只需适当的维护和更新,效果可以持续数年。我们提供优化后维护服务,确保您的网站长期保持竞争优势。
你们提供SEO优化效果保障吗?
我们提供基于数据的SEO效果承诺。根据服务套餐不同,我们承诺在约定时间内将核心关键词优化到指定排名位置,或实现约定的自然流量增长目标。所有承诺都会在服务合同中明确约定,并提供详细的KPI衡量标准。

SEO优化效果数据

基于我们服务的客户数据统计,平均优化效果如下:

+85%
自然搜索流量提升
+120%
关键词排名数量
+60%
网站转化率提升
3-6月
平均见效周期

行业案例 - 制造业

  • 优化前:日均自然流量120,核心词无排名
  • 优化6个月后:日均自然流量950,15个核心词首页排名
  • 效果提升:流量增长692%,询盘量增加320%

行业案例 - 电商

  • 优化前:月均自然订单50单,转化率1.2%
  • 优化4个月后:月均自然订单210单,转化率2.8%
  • 效果提升:订单增长320%,转化率提升133%

行业案例 - 教育

  • 优化前:月均咨询量35个,主要依赖付费广告
  • 优化5个月后:月均咨询量180个,自然流量占比65%
  • 效果提升:咨询量增长414%,营销成本降低57%

为什么选择我们的SEO服务

专业团队

  • 10年以上SEO经验专家带队
  • 百度、Google认证工程师
  • 内容创作、技术开发、数据分析多领域团队
  • 持续培训保持技术领先

数据驱动

  • 自主研发SEO分析工具
  • 实时排名监控系统
  • 竞争对手深度分析
  • 效果可视化报告

透明合作

  • 清晰的服务内容和价格
  • 定期进展汇报和沟通
  • 效果数据实时可查
  • 灵活的合同条款

我们的SEO服务理念

我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。

提交需求或反馈

Demand feedback