「非執行緒安全」其實會在多個執行緒對同乙個物件中的例項變數進行併發訪問時發生,產生的後果就是「髒讀」,也就是取到的資料其實是被更改過的。
1**、方法內的變數為執行緒安全的**
方法內部的私有變數,則不存在「非執行緒安全」的問題,所得結果也就是「執行緒安全」的。
2、例項變數非執行緒安全
如果多個執行緒共同訪問乙個物件中的例項變數,則有可能出現「非執行緒安全」問題。
用執行緒訪問的物件中如果有多個例項變數,則執行的結果有可能出現交叉的情況。
如果物件僅有乙個例項變數,則有可能出現覆蓋的情況。
為了避免「非執行緒安全」問題,在方法前加關鍵字 synchronized.1、物件例項
public
class hasselfprivatenum else
system.out.println(username+" num="+num);
}catch (interruptedexception e)
}}
在多個執行緒訪問同乙個物件中的同步方法時一定是執行緒安全的。synchronized
public
void
addi(string username)
或者public
synchronized
void
addi(string username)
同步是synchronized, 非同步是 asynchronized。
關鍵字synchronized取得的鎖都是物件鎖,而不是把一段**或方法(函式)當做鎖。哪個執行緒先執行帶synchronized關鍵字的方法,哪個執行緒就持有該方法所屬物件的鎖***lock,那麼其他執行緒只能是等待狀態,前提是多個執行緒訪問的是同乙個物件*。
但是如果多個執行緒訪問多個物件(不同的物件),則jvm會建立多個鎖。
呼叫關鍵字synchronized宣告的方法一定是排隊執行的(同步的)。只有共享資源的讀寫訪問才需要同步化,如果不是共享資源,根本沒有同步的必要。public
class run catch (interruptedexception e)
}}
1、(兩個執行緒分別訪問同乙個物件的 同步方法和 非同步方法)a執行緒先持有object物件的lock鎖,b執行緒可以以非同步的方式呼叫同乙個object物件中的非synchronized型別的方法。(非執行緒方法的呼叫不受影響)
2、(兩個執行緒分別訪問同乙個物件的 兩個不同的 同步方法)a執行緒先持有object物件的lock鎖,b執行緒如果呼叫同乙個物件的另乙個同步方法則需要等待,也就是同步。
三、髒讀—乙個執行緒在讀取資料,另乙個執行緒在設定資料(同乙個物件中,乙個是同步方法,乙個是非同步)。
發生髒讀的情況是在讀取例項變數時,此值已經被其他執行緒更改過了。(對於修改和讀取的方法都設定同步synchronized)
四、synchronized鎖重入—自己可以再次獲得自己的內部鎖
在使用synchronized時,當乙個執行緒得到乙個物件鎖後,(只要該執行緒還沒有釋放這個物件鎖,)再次請求此物件鎖時是可以再次得到該物件的鎖的。(也就是同步方法可以呼叫同乙個物件的另乙個同步方法)
可重入鎖也支援在父子類繼承的環境中。當存在父子類繼承關係時,子類是完全可以通過「可重入鎖」呼叫父類的同步方法。public
class
hasselfprivatenum
public
synchronized
void
adda(string username)
}
當乙個執行緒執行的**出現異常時,其所持有的鎖會自動釋放。public
class
subhasselfprivatenum
extends
hasselfprivatenum
}
五、同步不具有繼承性—同步不可以繼承
思考:如果一開始就呼叫同步的方法,那麼在該同步方法中存在呼叫其他方法(無論是否同步),都應該是同步的。//父類
public
class
hasselfprivatenum
}//子類
public
class
subhasselfprivatenum
extends
hasselfprivatenum
}多個執行緒呼叫子類的方法是非同步呼叫的。但是呼叫父類的方法,則是同步的
//非同步的物件
public
class
nosysntest catch (interruptedexception e)
}}//執行緒
public
class
countoperate
extends
thread
public
void
run()
}//同步的物件
public
class
hasselfprivatenum
}//執行
public
class
run
}//結果
//main執行緒並不是同步的,而是非同步的
//a、b執行緒是同步的,
sleep begin threadname=main time=1520412948959
sleep begin threadname=b time=1520412948969
sleep end threadname=main time=1520412953960
sleep end threadname=b time=1520412953969
sleep begin threadname=a time=1520412953969
sleep end threadname=a time=1520412958969
執行緒同步synchronized
synchronized只是保證在同乙個時刻,其他執行緒不能訪問鎖定的資源,但是其他方法或者是變數不能鎖定控制的 synchronized obj 上面語法格式中synchronized後括號裡的obj就是同步監視器,上面 的含義是 執行緒開始執行同步 塊之前,必須先獲得對同步監視器的鎖定。任何時刻...
synchronized同步方法
關鍵字synchronized 如果是在方法內的變數,則無所謂的的變數同步問題。因為在方法內部的變數都是私有的。synchronized如果是加在方法上面,則是對該物件的例項進行同步。如果有兩個執行緒同時對該方法進行操作,則會同步進行。對個例項多個執行緒,不存在同步的問題,那時jvm會生成多個鎖,應...
synchronized執行緒同步
public class testsyn implements runnable public synchronized voidm2 throws exception public void run catch exception e public static voidmain string a...