再不解決延遲不當,當心你的內存被打爆

摘要:這是在具體代碼中發現的不當延遲的問題,極端狀況下可能把內存打爆。

本文分享自華爲雲社區《線程中不當使用延遲問題》,原文做者:技術火炬手 。java

背景

這是在具體代碼中發現的不當延遲的問題,極端狀況下可能把內存打爆。算法

代碼DevLicenseServiceRoaDelegateImpl.javasegmentfault

定義:
image.pngapi

使用:
image.png數據結構

signalRefreshHelp 定義
image.png併發

這段代碼最大問題是使用延遲算法不當,在極端狀況下會致使內存暴漲,嚴重影響服務程序的性能。高併發

不要使用sleep來實現延遲

使用sleep實現延遲看起來很是直觀,可是這個在高併發、多請求、長期運行的服務程序裏必須特別當心。這是由於衡量服務程序性能的一個很是重要的指標是QPS, 就是服務程序的處理能力,通常狀況下越大越好;服務程序的總併發能力等於每一個線程的qps;單個線程的QPS = 1000毫秒 / (處理一個請求的毫秒);因此上面那個線程的QPS <= 1000 / 10000 = 0.1 (由於線程sleep了10000毫秒)。性能

這裏的處理邏輯是錯誤的!也有很嚴重的性能隱患,不過幸虧調用這個api 請求很少,纔沒有致使嚴重問題。測試

開發者的意圖是在建立一個任務後,延遲10s執行該任務,處理時序圖以下
image.pngspa

假如時間點t1 & t2 捱得很接近的話,線程在執行job1 & job2 也是很接近。

但實際的狀況變成:
image.png

就算建立job1 & job2的時間很接近,但job2執行的時間會比預期多了10s;連續提交的任務越多,越容易堆積,這些堆積的任務存放在 blocking queue,一直處處理完畢才刪除;若是這類請求不少的話,很容易引發內存爆掉。

解決方案

選擇合適的數據結構,默認線程池關聯的隊列是LinkedBlockingQueue , 沒有延遲控制,可使用DelayQueue
image.png

DelayQueue內部使用了PriorityQueue 按時間排序;須要本身使用Delayed 接口封裝請求數據

下面是例子
image.png

測試代碼,同時加入 3個須要延遲10s的任務
image.png

測試結果:
image.png

符合預期

點擊關注,第一時間瞭解華爲雲新鮮技術~

相關文章
相關標籤/搜索