Docker 的優點
1250
2025-04-02
點擊藍字關注我們
本文字數:978字
閱讀時間:3分鐘
★什么是線程安全?★
線程安全就是多線程訪問時,采用了加鎖機制,當一個線程訪問該類的某個數據時,進行保護,其他線程不能進行訪問直到該線程讀取完,其他線程才可使用。不會出現數據不一致或者數據污染。
舉一個例子:小明和小紅同時訪問同一個方法M(),而且他們在不同的線程中。小明所在的線程稱為A線程,小紅所在的線程稱為B線程,線程A和線程B有一個共享的變量G。小明去訪問方法M(),改變G的值為Ga,小紅也通過方法M()來改變G的值為Gb,正常情況下,小紅應該等小明訪問完成時再訪問,但當G的值還未變成Ga時,小紅就通過M()方法來訪問G了,此時G的值為假設為Ga’,本來小紅應該在Ga上進行改變,卻在Ga’上進行了改變,而且此時小明的線程還未結束,小明得到的也不再是Ga,這樣就導致的數據的錯誤,我們稱線程A和B之間是線程不安全的。
AlbertYang
★Java中什么時候考慮線程安全?★
單線程的時候我們無需考慮線程安全,這個不用多說,對于局部變量,每個線程執行時都會把局部變量放在各自棧幀的工作內存中,線程間不共享,故也不需要考慮線程安全問題。Java中有以下兩種變量需要考慮線程安全問題:
1. 靜態變量即類變量,位于方法區,為所有對象共享,共享一份內存,一旦靜態變量被修改,其他對象均對修改可見,故線程非安全。
2. 實例變量為對象實例私有,在虛擬機的堆中分配,若在系統中只存在一個此對象的實例,在多線程環境下,“猶如”靜態變量那樣,被某個線程修改后,其他線程對修改均可見,故線程非安全;如果每個線程執行都是在不同的對象中,那對象與對象之間的實例變量的修改將互不影響,故線程安全。
AlbertYang
★如何解決線程安全問題?★
Java中主要通過以下兩種方式解決線程安全問題:
1、同步方法
給多線程訪問的成員方法加上synchronized修飾符
public void synchronized M(){
// TODO
}
使用synchronized修飾的方法,就叫做同步方法,保證線程執行該方法的時候,其他線程只能在方法外等著,等該線程執行完成后其他線程才能繼續執行這個方法。
2、同步代碼塊
synchronized(同步鎖對象)
{
// 需要同步操作的代碼
}
對象的同步鎖可以想象是在對象上標記了一個鎖,而且對應了一個唯一的鑰匙,誰拿到鎖的鑰匙,誰就可以進入代碼塊,其他線程只能在代碼塊外面等著,在任何時候,Java虛擬機最多允許一個線程擁有該對象的同步鎖。
Java程序運行時可以使用任何對象作為同步監聽對象,但是一般的,我們把當前并發訪問的共享資源和變量作為同步監聽對象。
實際上,同步方法和同步代碼在本質上是一樣的,兩者都用了一個關鍵字synchronized,synchronized保證了多線程并發訪問時的同步操作,避免線程的安全性問題,但是有一個弊端,使用synchronized的方法或代碼塊,性能會比不用時要低一些,因此如果要用synchronized,應該盡量減小synchronized的作用域。
ALbertYang
你“在看”我嗎?
Java 任務調度
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。