Cache access in highly concurrent systems
Suppose I have two threads(Thread1, Thread2) where the threads are accessing the cache for a given object such as in the code below nearly at the same time:
Dim expensiveToGetData = Cache("ExpensiveDataKey")
If ExpensiveToGetData is nothing then
'because the cache has expired
ExpensiveToGetData = LoadExpensiveDataFromDataSource()
Cache("Expensiv开发者_C百科eDataKey") = ExpensiveToGetData
end If
ProcessExpensiveData(ExpensiveToGetData)
Isn't it possible for both threads to load the cache because they both requested data from the cache that was nothing/expired? I've run some tests on a local machine and it seems that the cache is being loaded more than once. Is this a normal pattern?
Yes, using that code it is certainly possible that two different request will get Nothing from Cache, and therefore both reload data. If you want to avoid this, you need to synchronize the whole operation of getting the data.
One way to do synchronize access, would be to use code similar to:
Dim expensiveToGetData = Cache("ExpensiveDataKey")
If ExpensiveToGetData is nothing then
SyncLock yourLockObject /* YourLockObject should be a Shared object. */
expensiveToGetData = Cache("ExpensiveDataKey")
If expensiveToGetData Is Nothing Then
ExpensiveToGetData = LoadExpensiveDataFromDataSource()
Cache("ExpensiveDataKey") = ExpensiveToGetData
End If
End SyncLock
end If
ProcessExpensiveData(ExpensiveToGetData)
The idea of checking whether we got the data before acquiring the lock, is to avoid excessive locking in an environment under high load. If it is not there, we need to check again once inside the lock, because another thread might have gotten the data while we were acquiring the lock.
Yes, it is possible, and it's not a desired pattern. As a quick fix you could establish a mutex lock on the cache as a quick fix, but ideally a better design would be to have the cache act as an intermediary load the expensive data itself. There is far more to that design pattern than I've alluded to, but it should get you started.
精彩评论