程序運行的時候,內存主要由如下部分組成:java
附一張圖片,會對java虛擬機有個總體的認識;
多線程
圖片來自https://www.zybuluo.com/867976167/note/51071ide
當多個線程執行同一個方法的時候,函數
何時可能會出現異常結果:url
多個線程共享一塊內存區域,在不加任何保護狀況下,對其操做;spa
何時可能會獲得正確的結果:線程
不使用共享內存,每一個線程內存空間相互獨立;code
多線程共享一塊內存區域,可是對這塊共享區域加鎖訪問;對象
狀況一(多個線程共享一塊內存區域,在不加任何保護狀況下,對其操做):blog
寫一個含靜態方法的類,求和,方法內用了一個靜態全局s(多個線程能夠同時訪問):
package com.pichen.java.static_; public class StaticTest { private static int s = 0; public static int sum(int n){ s = 0; for(int i = 0; i <= n; i++){ s += i; try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } return s; } }
寫一個Thread,調用上面的靜態方法:
package com.pichen.java.static_; public class ThreadCount implements Runnable{ @Override public void run() { while(true){ System.out.println(Thread.currentThread().getName() +":" +StaticTest.sum(100)); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } }
寫個Main函數,起三個線程,觀察運行結果,基本都是錯誤的:
package com.pichen.java.static_; public class Main { public static void main(String[] args) { ThreadCount t1 = new ThreadCount(); new Thread(t1).start(); ThreadCount t2 = new ThreadCount(); new Thread(t2).start(); ThreadCount t3 = new ThreadCount(); new Thread(t3).start(); } }
運行結果不符合預期:
Thread-0:13968 Thread-1:13968 Thread-2:13968 Thread-0:13033 Thread-1:13033 Thread-2:13033 Thread-1:14725 Thread-0:14725
緣由:多個線程同時對靜態全局變量s進行操做致使;
ps:這裏的例子是靜態全局變量s,其實有不少種狀況會引發結果異常問題,如在main方法中new出了一個對象,new出來的對象是存放在堆中的,多個線程共享,此時若是多線程同時操做該對象的話,也是有可能產生錯誤結果;
狀況二(不使用共享內存,每一個線程內存空間相互獨立):
修改靜態sum方法,使用局部變量s,以下:
package com.pichen.java.static_; public class StaticTest { private static int s = 0; public static int sum(int n){ int s = 0; for(int i = 0; i <= n; i++){ s += i; try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } return s; } }
運行程序,結果正確:
Thread-1:5050 Thread-0:5050 Thread-2:5050 Thread-0:5050 Thread-2:5050 Thread-1:5050 Thread-0:5050
狀況三(多線程共享一塊內存區域,可是對這塊共享區域加鎖訪問):
package com.pichen.java.static_; public class StaticTest { private static int s = 0; public synchronized static int sum(int n){ s = 0; for(int i = 0; i <= n; i++){ s += i; try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } return s; } }
@author 風同樣的碼農
@blog_urlhttp://www.cnblogs.com/chenpi/
運行程序,結果正確:
Thread-1:5050 Thread-0:5050 Thread-2:5050 Thread-0:5050 Thread-2:5050 Thread-1:5050 Thread-0:5050