今天收到一個客戶的反饋說excle導出的樣式亂了,我心想臥槽怎麼可能,然後看下客戶發來的excle,臥槽真的亂了,臥槽我發現這個亂的樣式有點眼熟啊!這個樣式不是另一個業務需求裏的excle的樣式嗎??多線程??併發???想了想不對,這個吊項目還併發,應該是代碼的原因。。
先給你們看下我的excle正常的樣式:
再給你們看看亂的樣式:就是業務A的樣式 被 業務B客串的樣式
查看了一下代碼發現我這段代碼其實是有問題的
這時我們來了解下ThreadLocal的原理
瞭解這個原理後,我們就知道其實:如果再在不停的new 線程的情況下 我得導出excle是沒有問題的,但是spring的servlet的線程管理肯定是線程池管理,也就會出現線程複用的情況,ThreadLocal恰恰是以線程作爲key存儲實例的,也就是說:
1、線程51:進入業務方法B
2、ThreadLocal發現沒有,然後存進map<線程51,業務方法B的實例>,
3、線程51處理完業務方法B——》空閒
4、前端請求業務方法A,線程51接單
5、然後ThreadLocal get到了實例,但是這個實例是業務方法B的實例
6、然後直接返回,執行業務方法A的操作,最終導致了業務方法A的數據格式混亂
最終的解決方法我改成了這樣不再使用ThreadLocal直接new
這是我認爲的,如果有大佬發現不對,請您及時留言指出,小弟謝謝了。