问题
I'm currently using a Hashtable wrapped as a Hashtable.Synchronized as a simple cache in a library that could be used by a multi-threaded environment (such as asp.net) - is this a suitable use for this collection? I understand that there are more suitable constructs available in .Net 4.0, but I'm stuck with .Net 3.5.
If it makes any difference, this cache is read from frequently, and is written to very infrequently (but needs to remain threadsafe).
Basic usage is something along the lines of:
Private Shared ReadOnly ExpressionCache As Hashtable = Hashtable.Synchronized(New Hashtable())
..snip...
If Not ExpressionCache.ContainsKey(myKey) Then
ExpressionCache(myKey) = myExpensiveOperationToInit()
End If
Return ExpressionCache(myKey)
..snip..
Am I doing something potentially dangerous here, or is this an acceptable use case?
回答1:
Actually, Hashtable
(unlike Dictionary<,>
) already has very good threading semantics for use as a cache: it is thread-safe for readers (but requires locking for writers) - from MSDN:
Hashtable is thread safe for use by multiple reader threads and a single writing thread. It is thread safe for multi-thread use when only one of the threads perform write (update) operations, which allows for lock-free reads provided that the writers are serialized to the Hashtable.
(it also mentions .Synchronized
for supporting multiple writers, but frankly taking control of this ourselves usually gives much better results)
However, to avoid phantom reads, you shouldn't use separate "contains" / "get" operations; standard use might be (using C# for the example):
public YourType Get(string key) {
return (YourType) expressionCache[key];
}
public void Set(string key, YourType value) {
lock(expressionCache) {
expressionCache[key] = value;
}
}
key points:
- only the "set" has any locking
- only a single operation in the "get"
- use the indexer, not
Add
, in the set (then you don't need to check "contains" first)
The .Synchronized
wrapper is actually of remarkably little value in most common threading scenarios.
来源:https://stackoverflow.com/questions/12554803/is-hashtable-synchronized-suitable-for-use-as-a-simple-cache-in-a-multithreaded