Matplotlib基礎繪圖
阿新 • • 發佈:2020-10-23
在講解volatile關鍵字的時候,我們先看一個簡單的例子:
package SynchronizedCass; public class t4 { public static void main(String[] args) { try { RunThread thread = new RunThread(); thread.start(); Thread.sleep(1000); thread.setRunning(false); System.out.println("已經被賦值為false"); } catch (InterruptedException e) { // TODO 自動生成的 catch 塊 e.printStackTrace(); } } } class RunThread extends Thread { private boolean isRunning = true; public boolean isRunning() { return isRunning; } publicvoid setRunning(boolean isRunning) { this.isRunning = isRunning; } @Override public void run() { super.run(); System.out.println("進入run方法了"); while(isRunning == true) { //無限迴圈 } System.out.println("執行緒被停止了!"); } }
進入run方法了 已經被賦值為false
從結果上看:System.out.println("執行緒被停止了!"); 這句程式碼從未被執行,程式進入了死迴圈,這是為什麼呢?
啟動執行緒後private boolean isRunning = true; 變數存在於記憶體的公共堆疊及執行緒的私有堆疊中。在JVM被設定為-server模式時為了執行緒執行的效率。執行緒一直在私有堆疊中取得isRunning的值是true;雖然程式碼thread.setRunning(false)被執行了,更新的卻是公共堆疊中的isRunning變數值false,執行緒的私有堆疊中任為true,所以執行緒thread就一直處於死迴圈的狀態。
這個問題就是公共堆疊中的值和私有堆疊中的值不同步造成的。那麼如何解決這個問題,這就到了我們今天要介紹的關鍵字volatile,當他修飾isRunning變數時,強制性地從公共堆疊中進行取值。
package SynchronizedCass; public class t4 { public static void main(String[] args) { try { RunThread thread = new RunThread(); thread.start(); Thread.sleep(1000); thread.setRunning(false); System.out.println("已經被賦值為false"); } catch (InterruptedException e) { // TODO 自動生成的 catch 塊 e.printStackTrace(); } } } class RunThread extends Thread { volatile private boolean isRunning = true; public boolean isRunning() { return isRunning; } public void setRunning(boolean isRunning) { this.isRunning = isRunning; } @Override public void run() { super.run(); System.out.println("進入run方法了"); while(isRunning == true) { //無限迴圈 } System.out.println("執行緒被停止了!"); } }
進入run方法了 已經被賦值為false 執行緒被停止了!
我們看一下使用volatile關鍵字後發生了什麼?
執行緒主體是不是強制地從公共記憶體中讀取變數的值,它增加了例項變數在多個執行緒之間的可見性。
比較一下關鍵字volatile和synchronized,如下:
- 關鍵字volatile解決的是變數在多個執行緒之間的可見性;而synchronized關鍵字解決的是多個執行緒之間的訪問資源的同步性。
- 關鍵字volatile只能用於修飾變數,而synchronized可以修飾方法,以及程式碼塊。
- 多執行緒訪問volatile不會發生阻塞,而synchronized會發生阻塞。
- volatile能保證資料的可見性,但是不能保證原子性;而synchronized可以保證原子性,也間接保證可見性(因為他會將私有記憶體和公共記憶體中的資料做同步)