## Java专题十三(3):内存模型、volatile、ThreadLocal
[TOC]
### JVM内存模型
![](https://img.kancloud.cn/73/a0/73a0393e9246be62b1885c1123ae4af8_486x435.png)
在JVM中主要分为Thread Stack和Heap,每一个线程都会复制一份局部变量到自己的线程栈中,所以一个线程对局部变量的改变对另一个线程是不可见的
- 线程栈(Thread Stack):存储了所有方法内部的局部变量(包括基本数据类型和对对象的引用)
- 堆区(Heap):存储了所有对象,成员变量(包括基本数据类型,且和所属对象一同存储在Heap中)
### 物理内存模型
![](https://img.kancloud.cn/52/6a/526af1d03f57b6fc3d8b42a7aa800f20_452x398.png)
物理内存模型包括3层,`CPU`、`CPU Cache Memory`、`Main Memory`,操作数据的速度排序:`CPU` > `CPU Cache Memory` > `Main Memory`,这里的`Main Memory`就是我们所说的内存。
当一个线程修改共享数据时,需要先从`Main Memory`读取共享数据到`CPU Cache Memory`时,当然只要它没有写回到`Main Memory`,对共享数据的改变就不会让其它线程知道,即对其它线程时不可见的
### volatile关键字
使用volatile关键字保证了对其它线程对变量写的可见性,具体表现如下
- 对volatile变量的每一次读取都是从`Main Memory`中读取的,而不是从`CPU Cache Memory`中读取的
- 对volatile变量的修改会马上写回到`Main Memory`中
如:`java.util.Thread`中声明的成员变量`private volatile String name;`
### ThreadLocal变量
`java.lang.ThreadLocal`是java提供的一个类,每个线程对`ThreadLocal`变量的读写操作(get和set方法)都保存着变量的一个副本,因此相对于其它线程来说是隔离互不影响的,但无法完成共享变量的操作,也就不存在所谓的线程安全问题
| 方法 | 寿命 |
| --- | --- |
| `void set(T value)`| 设置值 |
| ` T get()` | 获取值 |
| `T initialValue()`| 初始化值 |
| `void remove()` | 移除值 |
| `static <S> ThreadLocal<S> ` <br>` withInitial(Supplier<? extends S> supplier)` | 静态方法,初始化值 |
使用方法如下:
~~~
ThreadLocal<String> threadLocal = new ThreadLocal<String>(){
@Override
protected String initialValue() {
return "";
}
};
// can use with follow method to initial value
ThreadLocal<String> threadLocal1 = ThreadLocal.withInitial(new Supplier<String>() {
@Override
public String get() {
return "";
}
});
threadLocal.set("java");
threadLocal.get(); // "java"
threadLocal.remove(); // remove "java"
threadLocal.get(); // with initial value: ""
~~~
- JavaCook
- Java专题零:类的继承
- Java专题一:数据类型
- Java专题二:相等与比较
- Java专题三:集合
- Java专题四:异常
- Java专题五:遍历与迭代
- Java专题六:运算符
- Java专题七:正则表达式
- Java专题八:泛型
- Java专题九:反射
- Java专题九(1):反射
- Java专题九(2):动态代理
- Java专题十:日期与时间
- Java专题十一:IO与NIO
- Java专题十一(1):IO
- Java专题十一(2):NIO
- Java专题十二:网络
- Java专题十三:并发编程
- Java专题十三(1):线程与线程池
- Java专题十三(2):线程安全与同步
- Java专题十三(3):内存模型、volatile、ThreadLocal
- Java专题十四:JDBC
- Java专题十五:日志
- Java专题十六:定时任务
- Java专题十七:JavaMail
- Java专题十八:注解
- Java专题十九:浅拷贝与深拷贝
- Java专题二十:设计模式
- Java专题二十一:序列化与反序列化
- 附加专题一:MySQL
- MySQL专题零:简介
- MySQL专题一:安装与连接
- MySQL专题二:DDL与DML语法
- MySQL专题三:工作原理
- MySQL专题四:InnoDB存储引擎
- MySQL专题五:sql优化
- MySQL专题六:数据类型
- 附加专题二:Mybatis
- Mybatis专题零:简介
- Mybatis专题一:配置文件
- Mybatis专题二:映射文件
- Mybatis专题三:动态SQL
- Mybatis专题四:源码解析
- 附加专题三:Web编程
- Web专题零:HTTP协议
- Web专题一:Servlet
- Web专题二:Cookie与Session
- 附加专题四:Redis
- Redis专题一:数据类型
- Redis专题二:事务
- Redis专题三:key的过期
- Redis专题四:消息队列
- Redis专题五:持久化