場景:
公司項目需要做一個央行復雜報表的導出功能,需要渲染的源數據是通過存儲過程獲取,每次導出都需要將導出記錄落地到服務器備份,標記導出的批次,在落地是批次號需要保證唯一不重複,所以用戶使用導出功能的時候不能多人同時進行,也不能在一個導出功能在執行期間,同一個人再次點擊導出功能,否則會出現批次號重複錯誤,爲了保證同一時間內,只能有一個人執行導出功能,使用到synchronized代碼塊鎖技術。(ps:項目爲某保險公司運營管理系統,導出報表功能只有指定權限人員使用,如特定管理層人員,所以不會出現多人等待的不友好體驗。)
項目局部代碼圖:
解釋:
如下代碼是在ServiceImpl中控制的的鎖,首先在實現類ServiceImpl中定義一個static 的線程安全的ConcurrentHashMap用來存放鎖標記,然後如下進行代碼塊控制:
//記錄正在執行對比查詢的表
private static ConcurrentHashMap<String, String> currentExportReport = new ConcurrentHashMap<String, String>();boolean isExporting = false;
synchronized("currentExportReport"){
if(currentExportReport.get("Exporting") == null){
currentExportReport.put("Exporting","Exporting");
}else{
isExporting = true;
}
}if (isExporting) {
logger.info("同一表正在導出,請稍後導出。。。");
responseText = "{\"resCode\":\"1\",\"resMsg\":\"同一表正在導出,請稍後導出。。。\"}";
return responseText;}else {
//執行邏輯代碼區域
currentExportReport.clear();//同步代碼塊執行完畢後,需要釋放鎖
}
ConcurrentHashMap:
ConcurrentHashMap是一個經常被使用的數據結構,相比於Hashtable以及Collections.synchronizedMap() 在線程安全的基礎上提供了更好的寫併發能力,但同時降低了對讀一致性的要求。
ConcurrentHashMap詳細介紹可以借鑑博文http://www.importnew.com/22007.html,個人覺得寫得很nice。