synchronized ReentrantLock 執行緒安全
阿新 • • 發佈:2019-02-05
這段時間寫程式時,遇到一個問題,當多執行緒訪問某一個方法時,用synchronized保持同步並沒有起作用,反覆查了資料後,決定用ReentrantLock來替代synchronized,就解決了。原因是synchronized是物件鎖,也就是說多執行緒建立同一個物件去呼叫該方法,用synchronized是起作用的,然而當多個執行緒通過多個物件去呼叫該方法時則執行緒不安全。
解決方案,一個static的ReentrantLock ,在方法執行前加鎖,方法執行後解鎖,那麼此方法就執行緒安全了。
貼一段程式碼:
ReentrantLock 和 synchronized 有一點明顯的區別 —— lock 必須在 finally 塊中釋放。否則,如果受保護的程式碼將丟擲異常,鎖就有可能永遠得不到釋放!這一點區別看起來可能沒什麼,但是實際上,它極為重要。忘記在 finally 塊中釋放鎖,可能會在程式中留下一個定時炸彈,當有一天炸彈爆炸時,您要花費很大力氣才有找到源頭在哪。而使用同步,JVM 將確保鎖會獲得自動釋放。@Override public HandleStatus prepare() { try { lock.lock(); HandleStatus status = super.prepare(); if (!springInited) {// boolean變數得目的是讓static變數只初始化一次,但是prepare是每次都呼叫的 if(HandleStatus.isSuccess(status)){ initAndroidMobileMap(); initIosMobileMap(); initWpMobileMap(); status = HandleStatus.getSuccessOrFail(Utils.isNotEmpty(androidMobileMap,iosMobileMap,wpMobileMap)); } springInited = true; if(!HandleStatus.isSuccess(status)) logger.error(Utils.toLog("MobileChanger初始化失敗")); } return status; } finally { lock.unlock(); } }