關於多線程工作內存何時會刷新的問題探討


JMM 用來定義程序中變量的訪問規則,定義者,想要屏蔽掉不同的硬件和系統造成的內存訪問差異。

之前了解的JMM空也曾提到工作內存的概念,每個線程都有自己的工作內存,所有的變量多存在主內存,工作內存存儲的是各個線程用到的變量 主內存的副本拷貝,工作內存之間不能直接操作對方工作內存的變量,要通過主內存作為中間介,各個線程只能操作各自的工作線程變量,無法直接操作主內存變量。

然后就是就是定義了8中原子操作,用來控制變量,分別是 lock、unlock,read、load、use、assign、store、write。

定義了8個規則

1一個變量只能被一個線程lock,能被同一個線程多次lock,相應的要多次unlock,后面說的就是可重入。

2lock一個變量后,清除自己的工作內存先,再要使用時,重新從主內存加載;unlock后,要同步到主內存。

3變量只能定義在主內存,在使用user或者store前要load  或者assign

4工作內存的變量沒變化,不能平白無故同步主內存,一旦改變一定要同步主內存。

以上是基礎知識。摘自《深入了解java虛擬機》

 

再遇到兩個線程同時操作一個對象的字段時,遇到了一些問題,

先貼代碼

public class MyObject {
private String name="1";
private String pass="11";

public void print() {
System.out.println(name+" "+pass);
}

public void setvalue(String u,String p){
this.name=u;
if(Thread.currentThread().getName().equals("a")){
System.out.println("a停止 ");
Thread.currentThread().suspend();
}
this.pass=p;
}
}
public class Test {
public static void main(String[] args) throws Exception{
final MyObject object = new MyObject();
Thread thread2 = new Thread(){
@Override
public void run() {
while (true){
object.print();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
thread2.start();

Thread thread1 = new Thread(){
@Override
public void run() {
object.setvalue("a","aa");
}
};

thread1.setName("a");
thread1.start();
Thread.sleep(500);

//thread2.start();

}

描述:thread2和Thread1 會同時去操作一個object對象,
thread2運行后,輸出的 是1和11,在Thread1啟動后,會改變object的字段值,這時候thread2循環輸出的也變了,變成了a和11.

思考:
1每個線程都有自己的工作內存,會把object對象(字段為1,11)拷貝一份到thread2和Thread1的各自工作內存,第一次 thread2輸出字段為(1,11)可以理解。
2但是當Thread1  啟動后改變了期工作內存的object字段變成(a,11),
3接下來
thread2輸出字段為也變成了 (a,11)
於是接在思考不是有各自的工作內存嗎,線程thread1也沒有停止啊,為什么線程thread2的工作內存變量也會變掉。

以下是自己的看法
線程thread1的suspend()方法會同步到主內存,還有sleep()也是如此。
然后接下來就是怎么 主內存同步到 線程thread2的工作內存中

這是別人見解
為了提升性能,線程里面有工作內存,這樣訪問數據不用去主存讀取,可以快一些。共享變量被線程修改后,該線程的工作內存中的值就會和其他線程不一致,也和主存的值不一致,所以需要將工作內存的值刷入主存,但是這個刷入可能其他線程並沒有看到。
使用 volatile 后可以通過 cpu 指令屏障強制要求讀操作發生在寫操作之后,並且其他線程在讀取該共享變量時,需要先清理自己的工作內存的該值,轉而重新從主存讀取,volatile 保證一定會刷新,但是不寫也不一定其他線程看不見。

就是不一定,有隨機性,不加voliatile其他線程 也不一定看不見。加了一定看的見。
這就是目前我的理解。




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM