簡體   English   中英

Spring請求范圍vs java thread-local

[英]Spring Request scope vs java thread-local

在大量(每秒約50,000個請求)java web-app我正在使用ThreadLocal來執行應該按請求范圍執行的任務。

我可以使用Spring請求范圍實現相同的效果,我想知道哪個性能更好?

在代碼中,使用ThreadLocal:

private static final ThreadLocal<SomeClass> myThreadLocal = new ThreadLocal<SomeClass>();

並為每個http請求設置:

myThreadLocal.set(new SomeClass());

使用Spring請求范圍:

@Component
@Scope("request")
public class SomeClass{
...
}

現在,會花多少錢:

myThreadLocal.get();

要么

SpringContext.getBean(SomeClass.class);

我想知道是否有人已經嘗試過這樣的基准測試?

如果我們考慮傳統的Java方法,答案可以從下面的引用中減去,因為它要慢得多:

由於反射涉及動態解析的類型,因此無法執行某些Java虛擬機優化。 因此,反射操作的性能低於非反射操作,並且應避免在性能敏感應用程序中頻繁調用的代碼段中。

引自JavaDoc的反思 - http://java.sun.com/docs/books/tutorial/reflect/index.html

所以,因為Spring使用了反射getBean()方法的SpringContext.getBean(SomeClass.class); 方法應該更慢。

編輯

另請注意, ThreadLocal嵌入了緩存 ,只要您在這些線程中重復使用信息肯定會更快。

關於ThreadLocal解決方案,我想補充一點,您的Web服務器中可能存在一個線程池(例如:Tomcat),並且在完成每個請求后,您的線程局部變量實際上不會被清除,因為處理線程不會死已啟用線程池。

您需要在threadLocal.remove()每個請求時手動清除線程局部變量( threadLocal.remove() )。 為此,您可以使用某些Spring請求/響應攔截器的某種afterCompletion()

Spring解決方案的成本會更高,但會使IMO更清晰。 獲取,創建,初始化和存儲bean涉及許多步驟。 但是,您不必像ThreadLocal那樣考慮清除請求范圍的bean。 清除相應的ServletRequest時將收集它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM