高併發環境下的效能優化 非同步呼叫 Future

2021-10-25 09:36:00 字數 2800 閱讀 6624

在業務處理過程中,我們會經常遇到一次使用者請求往往會涉及到多個操作。以獲取使用者資訊及其賬戶餘額為例,它包含了從使用者中心獲取使用者基本資訊(t1)以及從使用者金融中心獲取其對應的賬戶餘額資訊(t2)

如果採用同步呼叫的話,總的響應時間將是 t1 + t2。

類似這種兩個子操作在執行過程中沒有依賴關係的呼叫切忌使用同步,這樣會大大降低系統的併發量。

下面我們介紹幾種使用非同步呼叫來來優化掉同步呼叫,從而縮短響應時間為max(t1,t2)

futuretask可用於非同步獲取執行結果或取消執行任務的場景。futuretask 實現了 runnablefuture 介面(繼承了future 和 runnable 介面)。

提供isdone操作可以查詢計算是否已經完成;

提供get操作獲取計算的結果,結果只可以在計算完成之後獲取,當計算沒有完成的時候get方法會阻塞;

提供cancel操作取消執行非同步計算;

乙個futuretask 可以用來包裝乙個 callable 或是乙個runnable物件。因為furturetask實現了runnable方法,所以乙個 futuretask可以提給乙個excutor或執行緒執行.

下面以futuretask 來優化剛開始的同步操作:

public static void testgetuserinfo()  catch (exception ex) 

return jsonobject.parseobject("");

}});

futuretask task2 = new futuretask(new callable() catch (exception ex)

return jsonobject.parseobject("");

}});

new thread(task1).start();

new thread(task2).start();

try catch (exception ex)

}

通過上面的例子,我們知道future介面提供了方法獲取計算的結果。但是這些特性還不足以讓你編寫簡潔的併發**。比如,我們很難表述future結果之間的依賴性;從文字描述上這很簡單,「當長時間計算任務完成時,請將該計算的結果通知到另乙個長時間執行的計算任務,這兩個計算任務都完成後,將計算的結果與另乙個查詢操作結果合併」。在此,通過completablefuture(它實現了future和completionstage介面)以更直觀的方式將上述需求都變為可能。

completablefuture.supplyasync(() -> );
有這樣乙個任務:

t由n個子任務構成,每個子任務完成的時長各不同。若其中有乙個子任務失敗,所有任務結束,t任務失敗。

enum result 

static listtasks = new arraylist<>();

public static void main(string args) throws exception

system.in.read();

}private static void callback(result result, mytask mytask)

}//處理流程結束

//通知其他執行緒結束回滾

//超時處理

}static class mytask

public result run()

} catch (exception ex)

system.out.println(name + " is ended!");

return ret;

}public void cancel() catch (exception ex)

system.out.println(name + " is cancelled");

cancelled = true;}}

}

completablefuture.allof(

completablefuture.supplyasync(() -> ),

completablefuture.supplyasync(() -> )

).whencomplete( (v, ex ) -> else ", ex );

}});

completablefuture.supplyasync(() -> catch (exception ex) 

system.out.println("write translog end");

return true;

}).thencombine(completablefuture.supplyasync(() -> catch (exception ex)

system.out.println("write to database end");

return false;

}), (b1, b2 ) -> b1 != null && b2 != null && b1 && b2)

.thencombine(completablefuture.supplyasync(() -> catch (exception ex)

system.out.println("write to syslog end");

return true;

}), (b1, b2 ) -> b1 != null && b2 != null && b1 && b2)

.whencomplete((b, ex) -> else

});try catch (exception ex)

併發環境下的快取容器效能優化(下) 效能測試

需要強調一點的是,我們這裡討論的僅僅是符合我提出的特定場景的快取容器,而不是乙個 執行緒安全的字典 或者說,其實我這裡更強調的是 併發環境下 的 讀 效能,而不涉及idictionary的其他操作 如count 更不會關心如copyto remove這類功能的效能。public inte ce ic...

高併發場景下優化伺服器的效能實戰

tcp nodelay引數並不是在作業系統級別進行配置的,而是在tcp套接字上新增tcp nodelay引數來關閉粘包演算法,以便使資料報能夠立即投遞出去。寫在前面 最近,有小夥伴在群裡提問 linux系統怎麼設定tcp nodelay引數?也有小夥伴說問我。那今天,我們就來根據這個問題來聊聊在高併...

高併發環境下的限流策略

在開發高併發系統時,有很多手段來防止系統過載 快取 降級 限流。快取的目的是提公升系統訪問速度和增大系統的吞吐量,降級和限流的目的如下 降級 降級是當服務出問題或者影響到核心流程的效能時需要暫時遮蔽掉某些功能,等高峰或者問題解決後再開啟。降級一般有幾種實現手段,自動降級和人工降級 1 通過配置降級開...