兩天沒解決的問題chatgpt用了5秒搞定隱藏bug
前言
一個說難不難,說簡單竟看不出來是哪里問題的一個bug。是的 可能自己能力和經驗尚淺無法識別,下面你們能否用火眼金睛一眼讓bug原形畢露
(這個問題是忽然暴露出來的,無任何征兆,沒人改動過,生產上運行了很長時間,故很奇怪,所以這個間諜看來很會隱藏)
隱藏的“間諜”
下面先來看代碼(偽代碼)
code
/** * 兩個從數據庫查詢的耗時任務 * @param countDownLatch * @param all */ public static void testCount(CountDownLatch countDownLatch, List<String> all) { for (int i = 0; i < 2; i++) { int finalI = i; ThreadPoolFactory.getGeneral().execute(() -> { try { List<String> countList = new ArrayList<>(); //這里之所以用for循環(huán),是因為查詢業(yè)務需要0和1兩個狀態(tài)去查詢 if (finalI == 0) { //這里其實是查詢數據庫的mapper操作,為了方便演示 countList.add("1"); countList.add("2"); countList.add("3"); } else { //這里其實是查詢數據庫的mapper操作,為了方便演示 countList.add("5"); countList.add("6"); countList.add("7"); countList.add("8"); } if (countList != null) { all.addAll(countList); } } catch (Exception ex) { ex.printStackTrace(); } finally { countDownLatch.countDown(); } }); } } //線程池類 public class ThreadPoolFactory { private static final Logger logger = LoggerFactory.getLogger(ThreadPoolFactory.class); private static final ThreadFactory GENERAL_THREAD_FACTORY = new ThreadFactoryBuilder().setNameFormat("general-pool-%d").build(); /** * corePoolSize:核心線程池大小 * maximumPoolSize:最大線程池大小 * keepAliveTime:線程最大空閑時間 * unit:時間單位 * workQueue:線程等待隊列 四種隊列 1.ArrayBlockingQueue:有界隊列,2.SynchronousQueue:同步隊列,3.LinkedBlockingQueue:無界隊列,4.DelayQueue:延時阻塞隊列 * threadFactory:線程創(chuàng)建工廠 * handler:拒絕策略 四種策略 1.ThreadPoolExecutor.AbortPolicy():2.ThreadPoolExecutor.CallerRunsPolicy():3.ThreadPoolExecutor.DiscardOldestPolicy():4.ThreadPoolExecutor.DiscardPolicy() */ private static final ExecutorService GENERAL = new ThreadPoolExecutor(5, 10, 30L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(4096), GENERAL_THREAD_FACTORY, new ThreadPoolExecutor.AbortPolicy()); public static ExecutorService getGeneral() { return GENERAL; } } //main方法測試 public static void main(String[] args) throws Exception { List<String> all = new ArrayList<>(); CountDownLatch countDownLatch = new CountDownLatch(2); testCount(countDownLatch,all); countDownLatch.await(10, TimeUnit.SECONDS); System.out.println(all); }
對于上面CountDownLatch不了解的的可以看下我歷史的文章: 干貨!CountDownLatch的使用場景
看到這里不知道你們能否看出端倪,先說問題結果吧,最后的這個all集合為空,生產上的接口也是同樣的問題,我上面的代碼是和生產上的1:1復制的偽代碼。
我先說下我的排查思路:
1、線程池問題,我認為是線程沒有被及時的回收,時間太長,并發(fā)數過高,導致線程不夠用,第一想到的是便是線程數需要增加
2、數據庫數據過多,導致查詢比以前慢出一個量級,最后隊列阻塞,拖垮線程(這個概率比較低,因為數據庫查詢很快返回,并沒有需要優(yōu)化的慢sql)
3、懷疑是這個循環(huán)造成的,比如某種機制少循環(huán)或者不循環(huán),去掉for循環(huán)依然沒解決問題
驗證第一位”間諜“
首先擴大核心線程數和最大線程數,將這倆參數擴大為10和20
private static final ExecutorService GENERAL = new ThreadPoolExecutor(10, 20, 30L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(4096), GENERAL_THREAD_FACTORY, new ThreadPoolExecutor.AbortPolicy());
擴大之后,放上去能查出數據了,感覺解決了這個大問題
那句話怎么說來著,真相往往不是那么的容易發(fā)現(xiàn),最先抓到的都是小魚小蝦,果不其然,運行了一周左右,同樣的問題又出現(xiàn)了,感覺這就是一水缸,你把水缸變大,終有蓄滿的一天。我們都知道,線程池可不是越大越好。
那么真相究竟是什呢,看到這里的小伙伴如果你已經有了答案,可以先去評論區(qū)評論,不要看下面的答案。
借助GPT“偵探柯南”
chatgpt這里我就不多說了,這個東西如果現(xiàn)在還不了解的,那我就。。。就只能求求你趕緊去了解下吧
我把生產上的代碼完整的貼上去,他是這樣回答的
不得不說,一語中的,僅5秒就把我們所能想到和不能想到的都回答出來了
- 很顯然,第二點,第三點我們基本上驗證通過了
- 那就是第一點了,其實我們早就應該想到這一點的,多線程環(huán)境下,線程安全問題是首位的?。?!
找出"真兇"
使用synchronized
關鍵字解決線程安全
使用synchronized
關鍵字來同步訪問all
列表,即在多個線程訪問all
列表時,使用同一個鎖來保證線程安全,避免出現(xiàn)數據不一致的問題。這樣就解決了多個線程可能會同時訪問并修改數據,導致數據丟失或損壞的問題。
聰明的你有沒有找出“真兇”呢???
還記得我們加大線程數來解決問題嗎,我又問了一個問題
擴大線程池的參數可能會提高程序的并發(fā)處理能力,但并不能從根本上解決問題。如果是由于數據同步問題導致的線程池查不到數據,那么擴大線程池只是把問題暫時推遲了而已。此外,擴大線程池的核心線程池數量也會占用更多的系統(tǒng)資源
AI已來,未來已來
再啰嗦一句,AI的強大這里就不再強調了 ,接下來我會持續(xù)利用GPT輸出很多干貨和其他AI生態(tài)的東西,都收在下方的AI專欄里,一起學習,一起成長,用一句話作為結尾吧: 將來淘汰你的不是AI,而是不會用AI的人
以上就是兩天沒解決的問題chatgpt用了5秒搞定的詳細內容,更多關于chatgpt 5秒解決問題的資料請關注腳本之家其它相關文章!
相關文章
java如何利用FastJSON、Gson、Jackson三種Json格式工具自定義時間序列化
本篇文章主要介紹了java如何利用FastJSON、Gson、Jackson三種Json格式工具自定義時間序列化,具有一定的參考價值,有興趣的可以了解一下2017-08-08springmvc fastjson 反序列化時間格式化方法(推薦)
下面小編就為大家?guī)硪黄猻pringmvc fastjson 反序列化時間格式化方法(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-04-04MyBatis中SqlSession實現(xiàn)增刪改查案例
這篇文章主要介紹了MyBatis中SqlSession實現(xiàn)增刪改查案例,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-03-03解決Java?properties文件里面如何寫"\"的問題
由于properties使用“\”相當于是java的轉義符,如果想要寫出\的效果,只需修改相應的寫法即可,對java?properties文件里的"\"寫法感興趣的朋友一起看看吧2022-04-04Spring @Primary和@Qualifier注解原理解析
這篇文章主要介紹了Spring @Primary和@Qualifier注解原理解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-04-04