简要概述java内存模型,以及volatile关键字

如果我们要想深入了解Java并发编程,就要先理解好Java内存模型。Java内存模型定义了多线程之间共享变量的可见性以及如何在需要的时候对共享变量进行同步。原始的Java内存模型效率并不是很理想,因此Java1.5版本对其进行了重构,现在的Java8仍沿用了Java1.5的版本。
在java中每个线程都有一块本地内存,而本地内存存放的变量是主内存的副本。相当于在线程启动时候线程会复制主内存的变量到自己的本地内存。当本地内存变量改变时候就同步到主内存。如果有多个变量线程共享变量,这时候主内存又会刷新同步所有线程的变量。而这种同步并不是实时的。

如何和证明每个线程内部都有一份主内存副本?
下面有段代码
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
package com.mylienkd;public class MyThread implements Runnable { private Integer nubmer=0; @Override public void run() { while(true){ if(nubmer>1){ System.out.println(Thread.currentThread()+"子线程循环结束"); break; } } } public void setNubmer(Integer nubmer) { this.nubmer = nubmer; } public static void main(String[] args) throws Exception { MyThread thread=new MyThread(); new Thread(thread).start(); //睡眠1s Thread.sleep(1000); thread.setNubmer(10); //睡眠3s Thread.sleep(3000); System.out.println("主线程结束"); }} |
在此运行此代码得到如下结果

仔细观察代码以及结果可以发现,在主线程更改变量nubmer为10后,主线程执行结束,但是控制台并没退出一直在执行。
这是因为子线程并没有退出循环。因为子线程本地内存的number为0,主内存中的值并没有刷新到子线程中的本内存的所以才会出现这种状态。
如何解决此方法。java为了避免这种情况提供了关键字volatile ,在number变量上加上volatile关键字
|
1
|
private volatile Integer nubmer=0; |
运行此代码得到结果

可以看到此代码在主线程退出前,子线程就先退出了循环。这是因为volatile关键字实时更新此变量。在number变量更改时,就同步刷新更改其他线程的副本变量。
在很多地方叫做volatile关键字解决可见性。
简要概述java内存模型,以及volatile关键字的更多相关文章
- Java内存模型与volatile关键字
Java内存模型与volatile关键字 一).并发程序开发 并行程序的开发要涉及多线程.多任务间的协作和数据共享问题. 常用的并发控制:内部锁.重入锁.读写锁.信号量. 二).线程的特点 线程的特点 ...
- Java内存模型中volatile关键字的作用
volatile作用总结: 1. 强制线程从公共内存中取得变量的值,而不是从线程的私有的本地内存中,volatile修饰的变量不具有原子性(修改一个变量的值不能同步). 2. 保证volatile修饰 ...
- Java并发编程:JMM(Java内存模型)和volatile
1. 并发编程的3个概念 并发编程时,要想并发程序正确地执行,必须要保证原子性.可见性和有序性.只要有一个没有被保证,就有可能会导致程序运行不正确. 1.1. 原子性 原子性:即一个或多个操作要么全部 ...
- Java内存模型:volatile详解
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt202 Java内存模型:volatile是干什么用的Volatile字段是用 ...
- Java内存模型与Volatile,Happen-Before原则等
Java的内存模型 Java内存模型(JMM)是一个抽象的模型.决定了线程主要定义了线程和内存间的抽象关系:主内存存放的是线程共享变量,每个线程有自己的工作内存,存放变量的副本,只能对副本进行读写, ...
- Java内存模型以及Volatile、Synchronize关键字的疑问
1.众所周知,java的内存模型是一个主内存,每个线程都有一个工作内存空间,那么主内存同步到工作内存是什么时候发生的呢?工作内存同步会主内存又是什么时候发生的呢? 在cpu进行线程切换时就会发生这些同 ...
- 【java】java内存模型(2)--volatile内存语义详解
多线程并发编程中synchronized和Volatile都扮演着重要的角色,Volatile是轻量级的synchronized,它在多处理器开发中保证了共享变量的“可见性”.可见性的意思是当一个线程 ...
- JMM 内存模型 与 volatile 关键字
内存模型 线程之间的共享变量存储在主内存(main memory)中,每个线程都有一个私有的本地内存(local memory). 本地内存中存储了该线程以读/写共享变量的副本. 不同线程之间无法相互 ...
- java内存模型与volatile变量与Atomic的compareAndSet
java分主内存和工作内存, 主内存是线程共享的, 工作内存是每个线程独有的. java对主内存的操作是通过工作内存间接完成的: 先拷贝主内存变量值到工作内存, 在工作内存操作这个变量的副本, 完成后 ...
随机推荐
- URI和URL的关系与区别
首先给大家举个例子,有一家公司的总经理,某天,给了我一张名片,上面写了他的头衔,北京XXX公司总经理 张三,还有他的办公室地址,北京市海淀区长安街35号北京XXX公司总经理办公室,那么,我以后给我的朋 ...
- Redis的安装(windows)
一.安装redis windows版本的下载在https://github.com/MicrosoftArchive/redis/tags msi是安装版,zip的解压就能用.建议下msi的. 下载挺 ...
- WUSTOJ 1347: GCD(Java)互质
题目链接:1347: GCD Description 已知gcd(a,b)表示a,b的最大公约数. 现在给你一个整数n,你的任务是在区间[1,n)里面找到一个最大的x,使得gcd(x,n)等于1. I ...
- 在论坛中出现的比较难的sql问题:25(字符串拆分3)
原文:在论坛中出现的比较难的sql问题:25(字符串拆分3) 最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了. 所以,觉得有必要记录下 ...
- 线程一(lock)
对于线程同步操作最简单的一种方式就是使用 lock 关键字,通过 lock 关键字能保证加锁的线程只有在执行完成后才能执行其他线程. lock 的语法形式如下. lock(object) { ...
- 链接标签<a>去掉下划线
1.去掉下划线 text-decoration:none:
- ssh免密登陆(简单快捷)
介绍免密登陆配合下边这张图可以了解下过程: 假设现在A要通过免密登陆B 在A上的操作: 1.终端输入ssh-keygen (后边可以指定加密算法:-t 算法,如果不指定就是默认的rsa) 原理: 首先 ...
- Spring之IOC原理及代码详解
一.什么是IOC 引用 Spring 官方原文:This chapter covers the Spring Framework implementation of the Inversion of ...
- Java 函数调用是传值还是传引用? 从字节码角度来看看!
原文地址:点击打开
- 记录java+testng运行selenium(二)---定义元素类及浏览器
一: 元素类 整体思路: 1. 根据状态可分可见和不可见两种 2. 同一个路径可以查找单个元素或多个元素 3. 获取元素text或者指定的value值 4. selenium对元素操作有两种,一是通过 ...