1. 程式人生 > >軟件構造 並發3(線程安全性)

軟件構造 並發3(線程安全性)

進行 res 變化 安全 簡單 相關 競爭 運行時 靜態變量

線程安全:數據類型或靜態方法在多線程中執行時,無論如何執行,不需調用者做額外的協作仍可以得到正確的行為。

行為正確意味著滿足規格說明和保持不變性 不能在前置條件中對調用者增加時間性要求(在set()運行時不能調用get())

例子:叠代器, 不是線程安全的。 叠代器的規範說,不能在叠代它的同時修改一個集合。 這是一個與調用者相關的時間相關的前提條件,如果違反它,Iterator不保證行為正確

線程安全的四個方法:①限制可變變量的共享②用不可變的共享變量③將共享數據封裝在線程安全的數據類型中④使用同步來防止線程同時訪問變量

限制可變變量的共享

:通過將數據限制在單個線程中,可以避免線程在可變數據上進行競爭。可變量的共享是競爭的主要原因

①局部變量保存在線程棧中,每個調用都有自己的變量副本 ,每個線程都有自己的堆棧。

②局部變量如果是對象的引用,則要確保不能引用任何其他線程可訪問 的對象。

避免全局變量:全局靜態變量不會自動受到線程訪問限制。如果使用了全局靜態變量,應說明只有一個線程會使用它們。最好在多線程環境中取消全局靜態變量

兩個線程若同時調用一個返回類的公眾靜態方法,會產生兩個實例,破壞了表示不變性。改造:采用限制的方式並自行確保只有一個線程訪問該方法;采用synchronized方式

HashMap也不是線程安全的

用不可變的共享變量:使用不可變的引用和數據類型。不可變解決了因為共享可變數據造成的競爭,並簡單地通過使共享數據不可變來解決它。

final變量是不可變的引用,所以聲明為final的變量可以安全地從多個線程訪問。(只能讀不能寫 因為這種安全性只適用於變量本身,仍然必須確保變量指向的對象是不可變的)

回憶不變性:類型是不可變的:如果類型的對象在其整個生命周期中始終表示相同的抽象值

但實際上,允許對rep進行改變,只要這些改變對客戶是不可見的,並且對應的抽象值不變(有益的突變)但是對於並發性,這種隱藏的變化是不安全的 , 使用有益的變

化的不可變數據類型必須使用鎖使自己線程安全。

軟件構造 並發3(線程安全性)