併發程式設計三大特性

2021-10-04 19:41:09 字數 1743 閱讀 2030

1.有序性

當**前後順序發生變化互不影響時,虛擬機會對**進行重排,但是這個操作可能會影響其他執行緒的執行,例子如下:

public class test 

});thread t2 = new thread(new runnable()

});t1.start();

t2.start();

t1.join();

t2.join(); //等待t1,t2執行緒的結束,避免a,b還沒賦值到map中就將其新增到set中

set.add("a="+map.get("a")+",b="+map.get("b")); //將map中的值新增到set中

system.out.println(set); //列印set}}

}

列印結果:

[a=0,b=0, a=1,b=0, a=0,b=1,a=1,b=1]

有上述4種輸出, 結果 1,1 是**發生重排後的結果。

2.可見性。

當兩個執行緒t1,t2呼叫乙個變數a時會發生的問題,首先t1從主存中讀取了a的值,並將a的值發生了改變,在t1將a的值送回主存中的時候,t2又從主存中讀取了a的值,但是t2讀取到的值是改變前的值,並不是t1返回給主存的值,此時就發生了問題。例子如下:

public class test4_1 

system.out.println("方法執行完畢");

}public static void main(string args)

}).start();

//這裡需要讓執行緒睡眠一會,因為執行的m方法一開始還會不斷向主存中讀取a的值。

try catch (interruptedexception e)

//將a的值改為false;

test.a = false;

system.out.println("a的值為" + test.a);

}}

3.原子性

完成乙個事物,事物中可能會有多個操作。要麼都執行,或者都不執行。

比如轉賬:小明轉給小紅100塊錢,假設這項事務 1.從小明錢包中扣除100元,2.將小紅錢包中的值加上100。在此過程中 如果第二步操作出現了異常,小紅的錢沒加上,而小明的錢已經扣除,這樣顯然是不行的,所以兩步操作要麼都執行,要麼都不知道。

例子**如下:

public class test4_2 

//列印執行完畢的執行緒名

system.out.println(thread.currentthread().getname() + "執行完畢");

}}).start();

}//使執行緒睡眠三秒鐘,給上面五個執行緒足夠的執行時間

thread.sleep(3000);

//列印a的值,可以發現上面五個執行緒執行完後a的值並不等於預想值。

system.out.println(a);

}}

在上述的操作中,列印a的值會小於等於500000000,原因就是沒***原子性,也就是可能會有多個執行緒執行到上述標記(1)中,他們獲取到的a的值是相同,但是他們都執行了a++然後將a的值返回到主存這個操作,也就是說返回的值比原來多了1,但是所有執行緒的執行次數大於1,所以最後的值會比預計的小或者等於。

解決辦法可以使用atomicinteger這個類,運用了cas原理

併發程式設計的三大特性

1 原子性 對於成員變數a來說,如果執行緒a執行以下操作 a 此時需要分三步執行 1 讀取a的值 2 將a的值加1 3 將加1後的值賦給a 在執行以上三步過程中,如果另乙個執行緒b對a進行了操作,那麼就不能保證原子性了。要保證原子性,可以加鎖,如synchronized 2 可見性 要理解可見性,需...

物件導向程式設計三大特性

類和物件的關係 類 而物件則是以類為模板所建立的。類的組成 物件建立記憶體模型 1 當程式開始執行,方法區以載入好程式所需類的位元組碼檔案。2 棧記憶體引導程式,當執行到需要建立物件時,會在堆記憶體中建立物件,此時物件的成員變數為初始值,成員方法為位址,指向方法區中的類成員方法。3 堆記憶體中所建立...

物件導向程式設計三大特性(csharp)

1.封裝 2.繼承 3.多型 不扯別的,看 就好 using system 程式的宣告 namespace demo0709 交通工具類 class transport public transport int id,string name public override string tostri...