synchronized ReentrantLock 線程安全

這段時間寫程序時,遇到一個問題,當多線程訪問某一個方法時,用synchronized保持同步並沒有起作用,反覆查了資料後,決定用ReentrantLock來替代synchronized,就解決了。原因是synchronized是對象鎖,也就是說多線程創建同一個對象去調用該方法,用synchronized是起作用的,然而當多個線程通過多個對象去調用該方法時則線程不安全。

解決方案,一個static的ReentrantLock ,在方法執行前加鎖,方法執行後解鎖,那麼此方法就線程安全了。

貼一段代碼:

 @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();
        }
    }
 ReentrantLock 和 synchronized 有一點明顯的區別 —— lock 必須在 finally 塊中釋放。否則,如果受保護的代碼將拋出異常,鎖就有可能永遠得不到釋放!這一點區別看起來可能沒什麼,但是實際上,它極爲重要。忘記在 finally 塊中釋放鎖,可能會在程序中留下一個定時炸彈,當有一天炸彈爆炸時,您要花費很大力氣纔有找到源頭在哪。而使用同步,JVM 將確保鎖會獲得自動釋放。

發佈了25 篇原創文章 · 獲贊 3 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章