并发基础_1_并发_底层实现

来源:互联网 发布:域名转国外注册商流程 编辑:程序博客网 时间:2024/06/13 19:17
Java并发机制的底层应用

Java代码在编译后会变成Java字节码,字节码被类加载器加载到JVM种,JVM执行字节码,最终需要转化为汇编指令在CPU上执行


Volatile的应用
volation是轻量级的synchronized,它在多处理器开发中保证了共享变量的"可见性"
可见性的意思是 当一个线程修改一个共享变量时,另外一个线程能读到这个修改的值。


1. Volatile的定义与实现原理
如果一个字段被声明为volatile,Java线程内存模型确保所有线程看到这个变量的值是一致的。


2. Volatile是如何保证可见性的?
a. 对声明volatile的变量进行写操作,JVM会向处理器发送一条Lock前缀的指令,将这个变量所在缓存行的数据写回到系统内存。

b. 在多处理器下,为了保证各个处理器的缓存是一致的,就会实现缓存一致性协议,
    每个处理器通过嗅探在总线上传播的数据来检查自己缓存的值是否过期了。

c. 当处理器发现自己缓存行对应的内存地址被修改,就会将当前处理器的缓存行设置成无效状态,
    对这个数据进行修改操作的时候,会重新从系统内存中读取数据到处理器缓存中


3. Volatile的特性
a. 可见性:
对于一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写入。
b. 原子性:
对任意单个volatile变量的读/写具有原子性!,但类似于volatile++这种复合操作不具有原子性!!!


4. Volatile 写 - 读的内存语义
volatile写的内存语义:
当写一个volatile变量时,JMM会把该线程对应的本地内存中的共享变量值刷新到主内存。

volatile读的内存语义:
当读一个volatile变量时,JMM会把该线程对应的本地内存置为无效;
线程直接从主内存中读取共享变量。

对volatile读和volatile写的内存语义来个小结
a. 线程A写一个volatile变量,实质上是线程A向接下来要读这个volatile变量的某个线程发出了(共享变量被修改的)消息。
b. 线程B度一个volatile变量,实质上是线程B接收了之前某个线程发出的消息
c. so,线程A写一个volatile变量,随后线程B接收了这个volatile变量,这个过程实质上是因为线程A通过主内存向线程B发送消息。

示意图




synchronized的应用

Java中的每一个对象都可以作为锁,具体表现为以下三种形式:(这个挺简单的,用过synchronized的都知道,这里不详述)
a. 对于同步方法,所示当前对象实例。
b. 对于静态同步方法,锁是当前类的Class对象。
c. 对于同步方法块,锁是Synchronized括号里配置的对象。

当一个线程试图访问同步代码块时,它首先必须得得到锁,退出或抛出异常时必须释放锁。
(往下的底层实现,不写了,自己看的都一脸懵逼..)




原子操作

原子的本意是"不能被进一步分割的最小粒子",而原子操作意为"不可被中断的一个或一系列操作"

处理器如何实现原子操作:
a. 首先处理器会自动保证基本的内存操作的原子性。
    意思是当一个处理器读取一个字节时,其他处理器不能访问这个字节的内存地址。

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

(了解就好,暂时不再往下深入)

原创粉丝点击