[EP2][線程基礎II][多線程資源競爭和併發安全]
=======
多線程資源競爭
什麼情況下會發生資源競爭?
- 單線程運行的程序不會發生資源競爭
單線程的程序 代碼按順序執行 符合人的
思路不會發生資源競爭 也不會存在線程
安全問題
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)