天天看點

銀行取款[多線程]{使用重入鎖Lock接口ReentrantLock鎖確定線程同步}

經典例子:老婆(朱麗葉)老公(羅密歐),使用銀行卡和存折,或者網銀等,同時對同一賬戶操作的安全問題。

 此處用多線程實作,同時取款的模拟實作,使用使用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,并且其他取款下,正确提示資訊。

多線程通路安全保證!