I am using Guava's Cache and have set concurrencyLevel
to 1
so the maximum capacity is utilized w.r.t. eviction is concerned. Following is my code:
CacheBuilder.newBuilder()
.maximumWeight(maxWeight)
.concurrencyLevel(1)
.expireAfterWrite(expireDuration, TimeUnit.MINUTES)
.removalListener(new RemovalListener<K, V>() {
@Override
public void onRemoval(RemovalNotification<K, V> removalNotification) {
log.warn(removalMsg + removalNotification.getKey());
}
})
.weigher(weigher)
.build();
Documentation of concurrencyLevel says this:
Guides the allowed concurrency among update operations. Used as a hint for internal sizing. The table is internally partitioned to try to permit the indicated number of concurrent updates without contention...
And hence I was assuming that the concurrencyLevel
plays a role only for update operations
and the READs are Lock Free
even with concurrencyLevel(1)
.
Is my assumption correct ??
EDIT:
I looked at the Guava Caching codeand it looks like my assumption that READs are lock free
is correct. In case of get(K, Callable)
initially it tries to get the value without lock and if the entry for the specified key is either null or has expired only then it goes for a locked Get or Load. Please Correct me if I am wrong here.
You can take a look at the code yourself. Most of the relevant stuff is in
LocalCache
.Anyway, from my understanding (I'm not an expert on the cache stuff), reads (on a non-
LoadingCache
) should generally be lock-free (on aLoadingCache
it depends on whether they need to load a value, in which case the read becomes a write too). In some code pathstryLock()
is used to acquire a lock, but since it'stryLock()
no reading threads should block if the lock is held I don't think.Edit:
From comments in
Segment
:(
concurrencyLevel(1)
currently means 1Segment
.)