經典例子:老婆(朱麗葉)老公(羅密歐),使用銀行卡和存折,或者網銀等,同時對同一賬戶操作的安全問題。
此處用多線程實作,同時取款的模拟實作,使用使用lock接口reentrantlock鎖確定線程同步,檢視取款安全隐患問題,代碼如下:
------------------------------------------------------------------------------------------------------------------------------------------------
* 線程同步 :使用重入鎖reentrantlock鎖,代碼編寫,實作線程同步
* reentrantlock 擁有synchronized相同的并發性和記憶體語義(reentrantlock可實作synchronized的所有功能,有更精确的線程語義和更好的性能)
* synchronized是在jvm層面上實作的,不但可以通過一些監控工具監控synchronized的鎖定,而且在代碼執行時出現異常,jvm會自動釋放鎖定;
* lock不會自動釋放鎖,lock是通過代碼實作的,要保證鎖定一定會被釋放,就必須将unlock()放到finally{}中
* 在javase5.0中新增了一個java.util.concurrent包來支援同步。reentrantlock類是可重入、互斥、實作了lock接口的鎖,它與使用synchronized方法和快具有相同的基本行為和語義,并且擴充了其能力
* 适用:在資源競争不是很激烈的情況下,synchronized的性能要優于reetrantlock
* 在資源競争很激烈的情況下,synchronized的性能會下降幾十倍,但是reetrantlock的性能能維持常态
*reentrantlock()還有一個可以建立公平鎖的構造方法,但由于能大幅度降低程式運作效率,不推薦使用
*reentrantlock在傳遞鎖等鎖中,例如"手拉手",更适用。
private void makewithdraw(int amount){
//add lock
lock.lock();
try {
//code
} catch (interruptedexception e) {
}finally{
//release lock must in the finally
lock.unlock();
}
}
銀行賬戶:
使用reentrantlock鎖,代碼:
測試代碼:
測試結果:
羅密歐 準備取款!
羅密歐 完成100取款!餘額為400
羅密歐 完成100取款!餘額為300
朱麗葉 準備取款!
朱麗葉 完成100取款!餘額為200
朱麗葉 完成100取款!餘額為100
朱麗葉 完成100取款!餘額為0
餘額不足以支付朱麗葉100 的取款,餘額為0
餘額不足以支付羅密歐100 的取款,餘額為0
分析結果:
雙線程總共取款10次,賬戶總額為500.
取款結果:在多線程通路下,成功取款總額為500,并且其他取款下,正确提示資訊。
多線程通路安全保證!