1. 程式人生 > >synchronized ReentrantLock 執行緒安全

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 將確保鎖會獲得自動釋放。