2010-10-07 14 views
6

W kodzie z listą 5.19 książki Brian Goetz Współbieżność w praktyce przedstawia swoją ukończoną wątek bezpieczną klasą Memoizer.W praktyce Współdziałanie Briana Goetza w praktyce, dlaczego jest jakiś czas (prawda) w ostatecznym przykładzie skalowalnej pamięci podręcznej?

Myślałem zrozumiałem kodu w tym przykładzie, oprócz tego, że nie rozumiem, co

while (true) 

jest na początku metody

public V compute(final A arg) throws InterruptedException 

.

Dlaczego kod wymaga pętli while?

Oto cały kod przykładowy

public class Memoizer<A, V> implements Computable<A, V> { 
    private final ConcurrentMap<A, Future<V>> cache 
     = new ConcurrentHashMap<A, Future<V>>(); 
    private final Computable<A, V> c; 

    public Memoizer(Computable<A, V> c) { this.c = c; } 

    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()); 
      } 
     } 
    } 
} 
+0

To samo uderzyło mnie, gdy po raz pierwszy przeczytałem. Myślę, że zgłosiłem to http://www.javaconcurrencyinpractice.com/errata.html, ale nigdy nie otrzymałem odpowiedzi. – jabley

+0

Tak, może książka musi być bardziej wyraźna na temat tej cechy rozwiązania (spróbuj ponownie po anulowaniu). – russelldb

Odpowiedz

8

Eternal pętli ponawia po wyjątku CancellationException. Jeśli zostanie zgłoszony inny wyjątek, wykonanie zostanie zatrzymane.

Biotext dot org ma numer blog entry w tym samym numerze.

+0

Tak. Jest dla mnie jasne, że ponownie je przeczytałem. Bardzo dziękuję za doskonały link. – russelldb

+0

Ale w próbie FutureTask nigdy nie zostanie anulowane. Czy możesz mi pomóc zrozumieć, w jaki sposób można wykonać tę ścieżkę kodu? – jabley

+0

FutureTask jest tworzony i dodawany do pamięci podręcznej. Niektóre inne procesy mogą pobrać zadanie z pamięci podręcznej i anulować je. –

1

Wygląda to tak, jakby głównym celem kodeksu jest obliczenie niezależnie od typu A jest. Wydaje się, że jedynym sposobem, aby while(true) mogła być efektywna, jest anulowanie. Jeśli nastąpi anulowanie, metoda spróbuje ponownie wykonać obliczenia.

Zasadniczo, while(true) zapewnia, że ​​(inny niż ExecutionException), w pewnym momencie funkcja zostanie ukończona i poprawnie obliczona nawet po anulowaniu.

Powiązane problemy