## Java專題十三(3):內存模型、volatile、ThreadLocal
[TOC]
### JVM內存模型

在JVM中主要分為Thread Stack和Heap,每一個線程都會復制一份局部變量到自己的線程棧中,所以一個線程對局部變量的改變對另一個線程是不可見的
- 線程棧(Thread Stack):存儲了所有方法內部的局部變量(包括基本數據類型和對對象的引用)
- 堆區(Heap):存儲了所有對象,成員變量(包括基本數據類型,且和所屬對象一同存儲在Heap中)
### 物理內存模型

物理內存模型包括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專題五:持久化