3535import java .util .Map ;
3636import java .util .Optional ;
3737import java .util .concurrent .CompletableFuture ;
38+ import java .util .concurrent .locks .Lock ;
39+ import java .util .concurrent .locks .ReentrantLock ;
3840import java .util .function .BiConsumer ;
3941import java .util .function .Consumer ;
4042
@@ -77,6 +79,7 @@ public class DataLoader<K, V extends @Nullable Object> {
7779 private final ValueCache <K , V > valueCache ;
7880 private final DataLoaderOptions options ;
7981 private final Object batchLoadFunction ;
82+ final Lock lock ;
8083
8184 @ VisibleForTesting
8285 DataLoader (@ Nullable String name , Object batchLoadFunction , @ Nullable DataLoaderOptions options ) {
@@ -93,7 +96,7 @@ public class DataLoader<K, V extends @Nullable Object> {
9396 this .batchLoadFunction = nonNull (batchLoadFunction );
9497 this .options = loaderOptions ;
9598 this .name = name ;
96-
99+ this . lock = new ReentrantLock ();
97100 this .helper = new DataLoaderHelper <>(this , batchLoadFunction , loaderOptions , this .futureCache , this .valueCache , this .stats , clock );
98101 }
99102
@@ -261,18 +264,16 @@ public CompletableFuture<List<V>> loadMany(List<K> keys, List<Object> keyContext
261264 nonNull (keys );
262265 nonNull (keyContexts );
263266
264- synchronized (this ) {
265- List <CompletableFuture <V >> collect = new ArrayList <>(keys .size ());
266- for (int i = 0 ; i < keys .size (); i ++) {
267- K key = keys .get (i );
268- Object keyContext = null ;
269- if (i < keyContexts .size ()) {
270- keyContext = keyContexts .get (i );
271- }
272- collect .add (load (key , keyContext ));
267+ List <CompletableFuture <V >> collect = new ArrayList <>(keys .size ());
268+ for (int i = 0 ; i < keys .size (); i ++) {
269+ K key = keys .get (i );
270+ Object keyContext = null ;
271+ if (i < keyContexts .size ()) {
272+ keyContext = keyContexts .get (i );
273273 }
274- return CompletableFutureKit . allOf ( collect );
274+ collect . add ( load ( key , keyContext ) );
275275 }
276+ return CompletableFutureKit .allOf (collect );
276277 }
277278
278279 /**
@@ -292,15 +293,13 @@ public CompletableFuture<List<V>> loadMany(List<K> keys, List<Object> keyContext
292293 public CompletableFuture <Map <K , V >> loadMany (Map <K , ?> keysAndContexts ) {
293294 nonNull (keysAndContexts );
294295
295- synchronized (this ) {
296- Map <K , CompletableFuture <V >> collect = new HashMap <>(keysAndContexts .size ());
297- for (Map .Entry <K , ?> entry : keysAndContexts .entrySet ()) {
298- K key = entry .getKey ();
299- Object keyContext = entry .getValue ();
300- collect .put (key , load (key , keyContext ));
301- }
302- return CompletableFutureKit .allOf (collect );
296+ Map <K , CompletableFuture <V >> collect = new HashMap <>(keysAndContexts .size ());
297+ for (Map .Entry <K , ?> entry : keysAndContexts .entrySet ()) {
298+ K key = entry .getKey ();
299+ Object keyContext = entry .getValue ();
300+ collect .put (key , load (key , keyContext ));
303301 }
302+ return CompletableFutureKit .allOf (collect );
304303 }
305304
306305 /**
@@ -376,9 +375,12 @@ public DataLoader<K, V> clear(K key) {
376375 */
377376 public DataLoader <K , V > clear (K key , BiConsumer <Void , Throwable > handler ) {
378377 Object cacheKey = getCacheKey (key );
379- synchronized (this ) {
378+ try {
379+ lock .lock ();
380380 futureCache .delete (cacheKey );
381381 valueCache .delete (key ).whenComplete (handler );
382+ } finally {
383+ lock .unlock ();
382384 }
383385 return this ;
384386 }
@@ -400,9 +402,12 @@ public DataLoader<K, V> clearAll() {
400402 * @return the data loader for fluent coding
401403 */
402404 public DataLoader <K , V > clearAll (BiConsumer <Void , Throwable > handler ) {
403- synchronized (this ) {
405+ try {
406+ lock .lock ();
404407 futureCache .clear ();
405408 valueCache .clear ().whenComplete (handler );
409+ } finally {
410+ lock .unlock ();
406411 }
407412 return this ;
408413 }
@@ -442,10 +447,13 @@ public DataLoader<K, V> prime(K key, Exception error) {
442447 */
443448 public DataLoader <K , V > prime (K key , CompletableFuture <V > value ) {
444449 Object cacheKey = getCacheKey (key );
445- synchronized (this ) {
450+ try {
451+ lock .lock ();
446452 if (!futureCache .containsKey (cacheKey )) {
447453 futureCache .set (cacheKey , value );
448454 }
455+ } finally {
456+ lock .unlock ();
449457 }
450458 return this ;
451459 }
0 commit comments