造轮子之MemorySafeLinkedBlockingQueue
造輪子之MemorySafeLinkedBlockingQueue-LinkBlockingQueue改進
LinkBlockingQueue改進
問題背景
https://github.com/apache/dubbo/pull/9722/files
使用線程池的同學對于標題中的隊列想必都有過使用,但上述隊列使用不當時則會造成程序OOM
,那怎么來控制呢?
使用ArrayBlockingQueue?如何來評估長度?
是否有一個完美的解決方案呢,MemorySafeLinkedBlockingQueue則通過對內(nèi)存的限制判斷盡面控制隊列的容量 ,完成解決了可能存在的OOM問題 。
獲取內(nèi)存大?。ㄗ? :單位大B;支持準實時更新):
Runtime.getRuntime().freeMemory()//JVM中已經(jīng)申請到的堆內(nèi)存中還未使用的大小Runtime.getRuntime().maxMemory()// JVM可從操作系統(tǒng)申請到的最大內(nèi)存值 -XxmRuntime.getRuntime().totalMemory()// JVM已從操作系統(tǒng)申請到的內(nèi)存大小 —Xxs可設(shè)置該值大小-初始堆的大小線程池在excute任務(wù)時,放隊列,放不進去 ,使用新線程運行任務(wù)。這個放不進行,是使用的offer??非阻塞方法嗎?
參考:https://blog.csdn.net/weixin_43108539/article/details/125190023
public void execute(Runnable command) { if (command == null) throw new NullPointerException(); //拿到32位的int int c = ctl.get(); //工作線程數(shù)<核心線程數(shù) if (workerCountOf(c) < corePoolSize) { //進入if
,代表可以創(chuàng)建 核心 線程數(shù) if (addWorker(command, true)) return; //如果沒進入if,代表創(chuàng)建核心線程數(shù)失敗,重新獲取 ctl c = ctl.get(); } //判斷線程池為Running狀態(tài),將任務(wù)添加入阻塞隊列
,使用offer if (isRunning(c) && workQueue.offer(command)) { int recheck = ctl.get(); //再次判斷是否為Running狀態(tài),若不是Running狀態(tài),remove任務(wù) if (! isRunning(recheck) && remove(command)) reject(command); //如果線程池在Running狀態(tài) ,線程池數(shù)量為0 else if (workerCountOf(recheck) == 0) //阻塞隊列有任務(wù)
,但是沒有工作線程,添加一個任務(wù)為空的工作線程處理阻塞隊列中的任務(wù) addWorker(null, false); } //阻塞隊列已滿