1
1
/*
2
- * Copyright 2002-2019 the original author or authors.
2
+ * Copyright 2002-2020 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
30
30
import java .util .Random ;
31
31
import java .util .concurrent .ConcurrentHashMap ;
32
32
import java .util .concurrent .ConcurrentLinkedQueue ;
33
- import java .util .concurrent .locks .Lock ;
34
33
import java .util .concurrent .locks .ReadWriteLock ;
35
34
import java .util .concurrent .locks .ReentrantReadWriteLock ;
36
35
import java .util .function .Function ;
@@ -421,9 +420,7 @@ private static class ConcurrentLruCache<K, V> {
421
420
422
421
private final ConcurrentHashMap <K , V > cache = new ConcurrentHashMap <>();
423
422
424
- private final Lock readLock ;
425
-
426
- private final Lock writeLock ;
423
+ private final ReadWriteLock lock ;
427
424
428
425
private final Function <K , V > generator ;
429
426
@@ -434,43 +431,36 @@ public ConcurrentLruCache(int maxSize, Function<K, V> generator) {
434
431
Assert .notNull (generator , "Generator function should not be null" );
435
432
this .maxSize = maxSize ;
436
433
this .generator = generator ;
437
-
438
- ReadWriteLock lock = new ReentrantReadWriteLock ();
439
- this .readLock = lock .readLock ();
440
- this .writeLock = lock .writeLock ();
434
+ this .lock = new ReentrantReadWriteLock ();
441
435
}
442
436
443
437
public V get (K key ) {
444
- V cached ;
445
-
446
- if ((cached = this .cache .get (key )) != null ) {
447
- if (this .size < this .maxSize / 2 ) {
438
+ V cached = this .cache .get (key );
439
+ if (cached != null ) {
440
+ if (this .size < this .maxSize ) {
448
441
return cached ;
449
442
}
450
-
443
+ this . lock . readLock (). lock ();
451
444
try {
452
- this .readLock .lock ();
453
- this .queue .add (key );
454
445
this .queue .remove (key );
446
+ this .queue .add (key );
455
447
return cached ;
456
448
}
457
449
finally {
458
- this .readLock .unlock ();
450
+ this .lock . readLock () .unlock ();
459
451
}
460
452
}
461
-
462
- this .writeLock .lock ();
453
+ this .lock .writeLock ().lock ();
463
454
try {
464
- // retrying in case of concurrent reads on the same key
465
- if (( cached = this .cache .get (key )) != null ) {
466
- this . queue . add ( key );
455
+ // Retrying in case of concurrent reads on the same key
456
+ cached = this .cache .get (key );
457
+ if ( cached != null ) {
467
458
this .queue .remove (key );
459
+ this .queue .add (key );
468
460
return cached ;
469
461
}
470
-
471
462
// Generate value first, to prevent size inconsistency
472
463
V value = this .generator .apply (key );
473
-
474
464
int cacheSize = this .size ;
475
465
if (cacheSize == this .maxSize ) {
476
466
K leastUsed = this .queue .poll ();
@@ -479,15 +469,13 @@ public V get(K key) {
479
469
cacheSize --;
480
470
}
481
471
}
482
-
483
472
this .queue .add (key );
484
473
this .cache .put (key , value );
485
474
this .size = cacheSize + 1 ;
486
-
487
475
return value ;
488
476
}
489
477
finally {
490
- this .writeLock .unlock ();
478
+ this .lock . writeLock () .unlock ();
491
479
}
492
480
}
493
481
}
0 commit comments