當前位置:成語大全網 - 書法字典 - 請簡要說明java中的線路安全是什麽?

請簡要說明java中的線路安全是什麽?

如果您的代碼位於多個線程同時運行的進程中,這些線程可能會同時運行該代碼。如果每次運行的結果與單線程運行的結果相同,並且其他變量的值與預期相同,則它是線程安全的。

換句話說,類或程序提供的接口是線程的原子操作或多線程之間的切換不會導致接口執行結果的模糊性,也就是說我們不必考慮同步問題。

線程安全問題由全局變量和靜態變量引起。

壹般來說,如果每個線程中對全局變量和靜態變量只有讀操作而沒有寫操作,那麽全局變量就是線程安全的。如果有多個線程同時執行寫操作,通常需要考慮線程同步,否則可能會影響線程安全。

例如,ArrayList類在添加元素時可能有兩個步驟:1。將此元素存儲在項目【Size】的位置;2.增加大小的值。

在單線程運行的情況下,如果Size = 0,在添加壹個元素後,該元素位於位置0,並且Size = 1;

例如,在多線程的情況下,有兩個線程,線程A首先將元素存儲在位置0。但此時,CPU會調度線程A暫停,而線程B獲得了運行的機會。線程B也將元素添加到這個ArrayList中,因為此時大小仍然等於0(註意,我們假設添加壹個元素需要兩個步驟,而線程A只完成了步驟1),因此線程B也將元素存儲在位置0。然後線程A和線程B都繼續運行,並且都增加了Size的值。

現在讓我們看看數組列表。實際上只有壹個元素,存儲在位置0,但大小等於2。這就是“線程不安全”。

編輯這個線程安全類必須在單線程環境中具有正確的行為才能是線程安全的。如果壹個類被正確實現(這是它符合規範的另壹種說法),那麽在這個類的對象上沒有操作序列(讀取或寫入公共字段並調用公共方法)來使對象處於無效狀態,並觀察到對象處於無效狀態,或者違反了該類的任何不變量、前置條件或後置條件。

此外,對於線程安全的類,當它被多個線程訪問時,無論運行時環境執行這些線程的時間或交錯如何,它都必須如上所述正確運行,並且被調用的代碼中沒有額外的同步。其效果是,在所有線程看來,對線程安全對象的操作以固定且全局壹致的順序發生。

正確性和線程安全之間的關系與描述ACID(原子性、壹致性、獨立性和持久性)事務時使用的壹致性和獨立性之間的關系非常相似:從特定線程的角度來看,不同線程執行的對象操作是順序的(盡管順序不確定)而不是並行的。

線程安全不是壹個真假命題。Vector的方法是同步的,Vector被明確設計為在多線程環境中工作。但是,它的線程安全性是有限的,即某些方法之間存在狀態依賴關系(同樣,如果Vector在叠代過程中被其他線程修改,Vector.iterator()返回的叠代器將引發並發的DefinitionException)。

對於Java類中常見的線程安全級別,沒有壹個分類系統可以被廣泛接受,但是在編寫類時盡可能多地記錄它們的線程安全行為是很重要的。

Bloch給出了壹種分類方法來描述五種線程安全:不變性、線程安全、條件線程安全、線程兼容和線程對立。只要清楚地記錄了離線安全功能,您是否使用該系統並不重要。這個系統有其局限性-類別之間的界限不是100%清晰,在某些情況下它沒有照顧到它們-但這個系統是壹個很好的起點。這個分類系統的核心是調用者是否可以或必須用外部同步來封裝操作(或壹系列操作)。下面幾節分別描述這五種線程安全。不可變不可變對象必須是線程安全的,並且永遠不需要額外的同步【1】。因為只要不可變對象構建正確,它的外部可見狀態就永遠不會改變,並且永遠不會在不壹致的狀態下看到它。Java類庫中的Integer、String、BigInteger等大多數基本數值類都是不可變的。線程安全線程安全對象具有上面“線程安全”壹節中描述的屬性-當對象被多個線程訪問時,類規範指定的約束仍然有效,無論運行時環境如何安排,線程都不需要任何額外的同步。這種線程安全保證非常嚴格——許多類(如Hashtable或Vector)無法滿足這種嚴格的定義。條件線程安全條件線程安全類對於單個操作可以是線程安全的,但是某些操作序列可能需要外部同步。條件線程安全最常見的例子是遍歷Hashtable或Vector返回的叠代器——這些類返回的fail-fast叠代器假設叠代器遍歷時底層集合不會改變。為了確保其他線程在遍歷時不會更改集合,叠代線程應該確保它對集合具有獨占訪問權限,以實現遍歷的完整性。通常,獨占訪問由鎖的同步來保證——並且類的文檔應該指出它是哪個鎖(通常是對象的內在監視器)。

如果您記錄壹個有條件線程安全的類,您不僅應該記錄它是有條件線程安全的,還應該記錄必須防止哪些操作序列被並發訪問。用戶可以合理地假設其他操作序列不需要任何額外的同步。線程兼容線程兼容類不是線程安全的,但是通過正確使用同步可以在並發環境中安全地使用。這可能意味著用synchronized塊封裝每個方法調用,或者創建壹個包裝器對象,其中每個方法都是同步的(就像Collections.synchronizedList())。這也可能意味著用同步塊封裝壹些操作序列。為了充分利用線程兼容的類,如果所有調用都使用同壹個塊,那麽調用方不應該被要求同步該塊。這樣做將使包含在其他線程安全對象中的線程兼容對象成為變量實例,以便可以利用其所有者對象的同步。

許多常見的類都是線程兼容的,例如集合類ArrayList和HashMap、java.text.SimpleDateFormat或JDBC類Connection和ResultSet。線程對線程對線程對線程對線程對線程對線程對線程對線程對線程對線程對線程對線程對線程對線程對線程對線程對線程對線程對線程對線程對線程對線程對線程對線程對對象類是那些當它們被並發使用時不能安全呈現的類,無論是否調用外部同步。線程對立很少見。當壹個類修改靜態數據時,這將影響在其他線程中執行的其他類的行為,通常會發生線程對立。線程對立類的壹個例子是調用System.setOut()的類。