首页 / JAVA / Java 并发——volatile
Java 并发——volatile
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Java 并发——volatile,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2836字,纯文字阅读大概需要5分钟。
内容图文
![Java 并发——volatile](/upload/InfoBanner/zyjiaocheng/847/2ea0fa31fb5742c7ae22e2b28f03c088.jpg)
JVM内存管理
概述
volatile 是轻量级的 synchronized。volatile 作用于共享变量,具备了“锁”的特性,这是为了确保共享变量能被准确和一致性地更新,这是 volatile 的可见性。同时,它也阉割了 scnchronized 的一写功能,比如:原子性。
内存模型
图如篇首。
首先我们应该明白CPU是执行命令的场所,当需要处理数据时,CPU会从主内存(计算机内存)中取值,这样很慢。后来有了CPU高速缓存(cache),也就是CPU上有一小块存储空间缓存了从主内存中获取的数据,CPU直接读取cache,效率大增。
然后,问题出现了,待处理的数据并非是主内存中的原型,而是一个副本,在多线程场景下,这个副本的处理结果很有可能会失控。这个问题也就是缓存一致性问题,即cache和主内存数据同步问题。目前我知道解决缓存一致性问题有两种方案:
通过在总线加LOCK锁
通过缓存一致性协议
第一种是通过独占CPU方式实现,同一时间只有一个CPU在运行,效率低下。
第二种允许多核处理,并且让共享副本在线程之间具有可见性。
可见性
通过 volatile 实现了缓存一致性,其工作原理如下:
当某个CPU在写数据时,如果发现操作的变量是共享变量,则会通知其他CPU告知该变量的缓存行是无效的,因此其他CPU在读取该变量时,发现其无效会重新从主存中加载数据。
volatile 的可见性只针对当CPU从主内存中加载共享变量的时候。但是当线程A、B同时加载了共享变量i,后者说线程A先加载了i,在A将i写入之前,B加载了i,B加载的i仍然是主内存中i的初始值。
非原子性
线程内存与主内存的交互过程如下:
主要有以下5项操作:
read:从主内存中读取变量
load:复制变量到线程本地内存作为副本
use:运算副本
assign:给副本赋值
store:副本写入线程本地内存
write:线程内存中的共享副本刷新主内存中的共享变量
上一章节——“可见性”中已经声明 volatile 的可见性只针对当CPU从主内存中加载共享变量的时候,即load之前,一旦load,无论主内存中的共享变量发生了什么,副本的值不会被主内存同步。也就是说,volatile不具有原子性。
网友解答:
volatile的非原子性:线程工作内容中的值从主内存中直接加载,一旦加载完成,就不会再产生对应的变化。JVM保证的是从主内存中加载到线程工作内存中的值是最新的,但是无法保证原子性。 volatile解决的是变量读时的可见性问题,无法保证原子性。
package com.zhoupq.multiThread.Volatile;
public class VolatileDemo implements Runnable
{
static volatile int i = 1;br/>@override
public void run() { system.out.println(thread.currentthread().getname() + ": " + i + ", "
- (++i));
}
public static void main(String[] args)
{
Thread t1 = new Thread(new VolatileDemo(), "A");
Thread t2 = new Thread(new VolatileDemo(), "B");
Thread t3 = new Thread(new VolatileDemo(), "C");
Thread t4 = new Thread(new VolatileDemo(), "D");
t1.start();
t2.start();
t3.start();
t4.start();
}
}
/
A: 1, 2
B: 1, 3
C: 3, 4
D: 4, 5
/
结果与预期不符,在预期的结果中,线程B应该加载的i是2,运算之后变成3。由此我们知道,volatile 不能解决并发计算问题。
网友解答:
- i 和+(++i)是两条指令,会发生这种情况:
假设当前i为1,线程A执行+i,线程B执行+i,然后线程A执行+(++i),这时i=2,然后线程B执行+(++i),这时i=3,线程A输出(1, 2),线程B输出(1, 3)。
小结
volatile 保证可见性
volatile 不保证原子性
volatile 不能解决并发计算问题
内容总结
以上是互联网集市为您收集整理的Java 并发——volatile全部内容,希望文章能够帮你解决Java 并发——volatile所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。