[Java併發編程][EP2][線程基礎II][多線程資源競爭和併發安全]

[EP2][線程基礎II][多線程資源競爭和併發安全]

=======

多線程資源競爭

什麼情況下會發生資源競爭?

  1. 單線程運行的程序不會發生資源競爭

單線程的程序 代碼按順序執行 符合人的
思路不會發生資源競爭 也不會存在線程
安全問題

JVM底層會進行一些,命令重排序方法內聯
等優化,導致代碼的執行順序可能和編寫的
不一致。但是Java內存模型會保證有先後順
序關聯的代碼,會被正確的安順訊執行。

  • 一個單線程運行的程序

public void testOneThread() {
  public static void main(String[] args) {
     OnePlainClazz onePlainClazz=new OnePlainClazz();
    onePlainClazz.run();
  }
}

public class OnePlainClazz {    

public void run() {
        int a=1;

        int b=2;

        int c=0;
        for(int i=0;i<1000;i++)
        {        int var=a+b;
                  c=var+c;
        }    
        System.out.println(c);
        }    
 
}

運行的結果 是可知的 爲3000

但是多線程時 卻不是這樣
多線程程序運行時 程序由系統調度
現代操作系統一般是亂序執行的
所以 在多線程時 程序執行順序並不是
你預想中的執行順序

  • 一個多線程併發運行的程序

線程併發安全


public void testMultiThread() {    
OnePlainClazz onePlainClazz=new OnePlainClazz();

  Thread runer1=new Thread(){    
  @Override
  public void run() {
  onePlainClazz.runCommon();
  }
 };

  Thread runer2=new Thread(){    
  @Override
  public void run() {
  onePlainClazz.runCommon();
  }
 };

  Thread runer3=new Thread(){
  @Override
  public void run() {
  onePlainClazz.runCommon();
  }
  
};


public class OnePlainClazz {    
 public void run() {
 
    private int ca=1;
    private int cb=2;
    private int res=0;
    
    public void runCommon() {      
    for(int i=0;i<10000;i++)
         {  
            int var=ca+cb;
            res=var+res;
         }    
     System.out.println(res);
    }
 }

此程序的運行結果
顯然不是30000

運行一次 結果:

39750
44826
40221

這種運行結果和預期結果不一致的情況
就是多線程不安全導致的

那麼怎麼解決此問題呢

一個辦法就是 加鎖
保證每一時刻只有一個線程能訪問此段代碼

加鎖後 同一時刻只有一個線程
能訪問此段代碼 那麼其他線程
呢? 只能等待 等待此線程執行完
並釋放鎖 然後等待的線程要重新
獲取鎖才能執行代碼段

此時 就成產生了資源競爭

線程併發安全

每個人肯定不希望自己的程序不按照預想的情況執行
而要最大程度利用硬件的性能,那麼多線程是不可避免
的。所以保證多線程併發安全,讓多線程程序也按照預
設執行就是程序員的責任。那麼什麼情況下是線程安全
的,什麼情況下是線程不安全的呢?

這就需要理解Java內存模型(Java Memory Model)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章