[英]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.