線程靜態標記靜態字段的值對於每個線程都是唯一的。簡單來說,是只應用在靜態字段上,而且對於每一個線程都是獨立存儲的。
那么,結合對象緩存來說,需求如下:
1、一些工具類,需要占用一定資源,但又不希望太頻繁的創建該工具類。
2、需要適應多線程的情況
一個例子就是StringBuilder類,StringBuilder類內部實現使用了char[]來存儲字符,我們需要使用StringBuilder來創建字符串,而且希望不太頻繁的創建它,避免內存壓力。
下面,就是.NET Framework 4.5.1 中對StringBuilderCache的實現:
internal static class StringBuilderCache{ private const int MAX_BUILDER_SIZE = 360; [ThreadStatic] private static StringBuilder CachedInstance; public static StringBuilder Acquire(int capacity = StringBuilder.DefaultCapacity){ if(capacity <= MAX_BUILDER_SIZE){ StringBuilder sb = StringBuilderCache.CachedInstance; if (sb != null){ if(capacity <= sb.Capacity){ StringBuilderCache.CachedInstance = null; sb.Clear(); return sb; } } } return new StringBuilder(capacity); } public static void Release(StringBuilder sb){ if (sb.Capacity <= MAX_BUILDER_SIZE){ StringBuilderCache.CachedInstance = sb; } } public static string GetStringAndRelease(StringBuilder sb){ string result = sb.ToString(); Release(sb); return result; } }
帶完整注釋的版本可以參考:http://www.projky.com/dotnet/4.5.1/System/Text/StringBuilderCache.cs.html
采用StringBuidlerCache類的例子是String.Join方法,可以參考:http://www.projky.com/dotnet/4.5.1/System/String.cs.html
不得不贊一下,這樣的設計非常巧妙。.NET 中程序的執行都在線程中,每個線程都有自己單獨的緩存,再也不用擔心同步、加鎖的問題,而且對於緩存的對象設置了大小限制。
再總結下它的原理:通過線程靜態賦予了靜態字段在多線程中獨立存儲的能力,再通過操作該靜態字段來存儲緩存對象。