最近有一個開發的需求須要從服務器下載相關的照片憑證文件,服務器中須要先下載壓縮打包後供客戶下載。數據庫
邏輯思路是:服務器
1.獲取數據庫中憑證的url多線程
2.在服務器上根據對應的url下載圖片,寫入指定的文件夾(臨時建立)併發
3.壓縮整個文件夾並經過response返回給用戶性能
4.刪除臨時建立文件和文件夾優化
5.overthis
(說明:指定的文件夾是臨時建立的,不一樣的用戶建立的文件夾名字一致。)url
-----------------------------------------------解決思路------------------------------------------------------------------ spa
從需求中就能夠看出代碼涉及了服務器上同一個文件夾的寫操做,若是多個用戶在差很少時刻點擊打包按鈕,那麼有可能會產生衝突,須要進行多線程同步操做。你們都知道SpringMVC 的controller默認是單例模式,所以在controller中進行代碼同步操做是沒有問題的。線程
第一次是直接在controller的對應方法中加入了synchronized關鍵字。顯然這種作法是很是不負責任的,由於在controller中也會涉及數據庫的讀操做,這些操做是能夠併發執行的。可是synchronized關鍵字會將整個controller方法變成同步方法,不一樣的線程須要排隊執行,下降了併發效率。
最好的方法是在相關的文件寫操做的地方進行
synchronized(this){
//FileIO operation
}
這就是細化同步代碼塊的粒度,減少原子大小,儘量發揮線程併發的優點。
ps:其實能夠經過每一個線程建立惟一目錄的形式去解決多線程衝突問題性能還更好,算是能夠優化的地方吧,可是應用併發量小就不作考慮了。今天發現了問題作了一個記錄^_^