java多執行緒 執行緒之間的可見性

2021-08-28 06:43:08 字數 2834 閱讀 9331

目錄

一、簡介

二、volatile

三、synchronized

四、不會從主記憶體拉取的操作

五、從主記憶體中拉取的操作

我們知道執行緒在工作的時候有自己的私有記憶體,工作記憶體。程式執行的時候從主記憶體拉取需要的變數到工作記憶體,處理完再返回主記憶體。這篇文章總結哪些**會使執行緒去主記憶體拉取變數。

volatile修飾的變數,不論什麼語句都會從主記憶體拉取變數。

public class test01 

system.out.println("end");

}public static void main(string args)

}).start();

try catch (exception e)

system.out.println("set");

test.b = false;

}}

該程式能順利完成,不會死迴圈。

呼叫其他synchronized加鎖的**塊,系統會從主記憶體拉取變數

public class test01 

}system.out.println("end");

}public static void main(string args)

}).start();

try catch (exception e)

system.out.println("set");

test.b = false;

}}

這種情況同樣不會死迴圈。

注意,synchronized加鎖後用到的變數才會從主記憶體拉取。

public class test01 

}system.out.println("end");

}public static void main(string args)

}).start();

try catch (exception e)

system.out.println("set");

test.b = false;

}}

這種情況,程式會死迴圈。 

只要不影響到變數的值,變數不參與運算,則不會從主記憶體中拉取,比如while,if,賦值給其他變數,作為方法引數等

public class test01 

boolean value = b;

}system.out.println("end");

}public void dosomething()

public static void main(string args)

}).start();

try catch (exception e)

system.out.println("set");

test.b = false;

}}

這種情況,程式會死迴圈。

如果呼叫了被synchronized加鎖的方法,或者方法中有被synchronized加鎖的**塊,那麼變數將會從主記憶體中拉取。

public class test01 

system.out.println("end");

}public void dosomething()

}public static void main(string args)

}).start();

try catch (exception e)

system.out.println("set");

test.b = false;

}}

呼叫的synchronized加鎖的方法即使鎖的是毫不相干的物件,同樣會使得變數從主記憶體拉取

public class test01 

system.out.println("end");

}public static void main(string args)

}).start();

try catch (exception e)

system.out.println("set");

test.b = false;

}}

這裡的system.out.println鎖的是printstream的例項,更是毫不相關

這種情況,程式不會死迴圈。 

變數被賦值,變數參與計算,比如加減乘除,字串拼接,++,--等操作,執行緒休眠會使從主記憶體中拉取變數。

public class test01  catch (interruptedexception e) 

}system.out.println("end");

}public static void main(string args)

}).start();

try catch (exception e)

system.out.println("set");

test.b = false;

}}

public class test01 

system.out.println("end");

}public static void main(string args)

}).start();

try catch (exception e)

system.out.println("set");

test.b = false;

}}

這種情況,程式不會死迴圈

Java多執行緒可見性(一)

一 記憶體可見性 執行緒對共享變數的修改,可以及時的被其他執行緒看到。那何為共享變數呢?就是在多個執行緒的工作記憶體中存在 如下圖所示 所謂的共享變數就是主記憶體中名為s的變數,程式中所有的變數都會儲存在主記憶體中 其他執行緒也會有自己的工作記憶體,此工作記憶體的作用是為執行緒與主記憶體之間建立橋梁...

多執行緒學習 執行緒可見性

每個執行緒都有自己的空間去暫存資料 當有乙份資料在a,b執行緒之間共享 那麼在a執行緒中改變了b是不會馬上知道的 example 共享物件 多個物件在沒有同步的情況下會發生可見性的錯誤 public class sharingobjects1 system.out.println thread th...

JAVA多執行緒 共享變數的可見性問題

我們知道執行緒在工作的時候有自己的私有記憶體,工作記憶體。程式執行的時候從主記憶體拉取需要的變數到工作記憶體,處理完再返回主記憶體。這篇文章總結哪些 會使執行緒去主記憶體拉取變數。volatile修飾的變數,不論什麼語句都會從主記憶體拉取變數。該程式能順利完成,不會死迴圈。因為 isstop 用vo...