Parallel Cache in Java

I need to find an explanation of the following code from conrianrency book by Brian Goetz.

public V compute(final A arg) throws InterruptedException { while (true) { Future<V> f = cache.get(arg); if (f == null) { Callable<V> eval = new Callable<V>() { public V call() throws InterruptedException { return c.compute(arg); } }; FutureTask<V> ft = new FutureTask<V>(eval); f = cache.putIfAbsent(arg, ft); if (f == null) { f = ft; ft.run(); } } try { return f.get(); } catch (CancellationException e) { cache.remove(arg, f); } catch (ExecutionException e) { throw launderThrowable(e.getCause()); } } } 

Also, after calling putIfAbsent (), why the operator f = ft; , and not just directly executing ft.run ()?

+1
source share
3 answers

The return value of putIfAbsent is existing if it already exists or null if it did not exist, and we put a new one.

  f = cache.putIfAbsent(arg, ft); if (f == null) { f = ft; ft.run(); } 

So, if ( f == null ) means "Have we put ft in the cache?". Obviously, if we did put it in the cache, we now need to set f to the one in the cache, i.e. ft .

If we did not put ft in the cache, then f already the one in the cache, because this is the value returned by putIfAbsent .

+1
source

Because you are returning f.get () and possibly removing f from the cache. This allows you to use one piece of code for all instances.

  try { return f.get(); } catch (CancellationException e) { cache.remove(arg, f); 

If you did not replace f with a reference to ft in the above, you will get NPE EVERY time putIfAbsent returned null.

0
source

The idea of ​​the code is as follows. The request to calculate some values ​​comes from different threads. If one thread initiated the calculation of a certain value, other threads that need the same result should not duplicate the calculations and should wait for the initial calculations. When the calculation is completed, the result is stored in the cache.

An example of such a template is loading java classes. If a class is loading, and another thread also asks to load the same class, it should not load it itself, but wait for the result of the first thread, so there is always no more than an instance of this class loaded by the same class loader.

0
source

Source: https://habr.com/ru/post/954455/


All Articles