若是咱們要想深刻了解Java併發編程,就要先理解好Java內存模型。Java內存模型定義了多線程之間共享變量的可見性以及如何在須要的時候對共享變量進行同步。原始的Java內存模型效率並非很理想,所以Java1.5版本對其進行了重構,如今的Java8仍沿用了Java1.5的版本。java
在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(
"主線程結束"
);
}
}
|
在此運行此代碼獲得以下結果ide
仔細觀察代碼以及結果能夠發現,在主線程更改變量nubmer爲10後,主線程執行結束,可是控制檯並沒退出一直在執行。post
這是由於子線程並無退出循環。由於子線程本地內存的number爲0,主內存中的值並無刷新到子線程中的本內存的因此纔會出現這種狀態。this
如何解決此方法。java爲了不這種狀況提供了關鍵字volatile ,在number變量上加上volatile關鍵字spa
1
|
private
volatile
Integer nubmer=
0
;
|
運行此代碼獲得結果線程
能夠看到此代碼在主線程退出前,子線程就先退出了循環。這是由於volatile關鍵字實時更新此變量。在number變量更改時,就同步刷新更改其餘線程的副本變量。code
在不少地方叫作volatile關鍵字解決可見性。