2013-04-19 7 views
7

Załóżmy, że muszę wykonać kilka równoczesnych zadań.Kiedy Futures mogą być bardziej odpowiednie niż Aktorzy (lub odwrotnie) w Scali?

Mogę zawijać każde zadanie w Future i czekać na ich zakończenie. Alternatywnie mogę utworzyć Actor dla każdego zadania. Każdy Actor wykona swoje zadanie (np. Po otrzymaniu komunikatu "start") i wyśle ​​wynik z powrotem.

Ciekawe, gdy należy użyć pierwszej (z Future s), a drugi (z Actor S) podejścia i czemu podejście Future jest uważane za korzystniejsze dla przypadku opisanym powyżej.

Odpowiedz

6

Ponieważ jest prostszy syntaktycznie.

val tasks: Seq[() => T] = ??? 
val futures = tasks map { 
    t => future { t() } 
} 
val results: Future[Seq[T]] = Future.sequence(futures) 

results przyszłość można następnie czekać na wykorzystaniu Await.result lub można mapować go dalej/używać go w do-zrozumienia lub wywołania zwrotne zainstalować na nim.

Porównaj to, aby utworzyć instancję wszystkich aktorów, wysyłając do nich wiadomości, kodując ich bloki receive, odbierając od nich odpowiedzi i zamykając je - co zwykle wymaga więcej kart.

+0

Jedyna różnica polega tylko na składni. Czy to jest poprawne? – Michael

+2

Różnica dotyczy również implementacji podstawowej, ale model Aktora jest generalnie silniejszym i bardziej ekspresyjnym modelem programowania - prawdopodobnie można utworzyć interfejs API podobny do interfejsu Futures API przy użyciu aktorów. Wdrażanie aktorów wykorzystujących przyszłość byłoby bardziej uciążliwe. – axel22

+0

Ok, widzę różnicę między modelami. Czy mógłbyś wyjaśnić również różnicę pomiędzy implementacjami? – Michael

5

Zgodnie z ogólną zasadą, należy użyć najprostszego modelu współbieżności, który pasuje do aplikacji, a nie najpotężniejszego. Zamawianie od najprostszych do najbardziej złożonych byłoby programowaniem sekwencyjnym-> kolekcje równoległe-> futures-> aktorzy bezstanowi-> aktorzy stanowi-> wątki z pamięcią transakcyjną oprogramowania-> wątki z wyraźnym blokowaniem-> wątki z algorytmami bez blokady. Wybierz pierwszą na tej liście, która rozwiąże Twój problem. Im dalej w dół tej listy, tym większa złożoność i ryzyko, więc lepiej jest handlować prostotą dla konceptualnej mocy.

+0

Skąd wziąłeś tę sekwencję? Dla mnie wygląda to niekonsekwentnie, ponieważ używanie kontraktów terminowych oznacza wątki z wyraźnym blokowaniem. I gdzie są wątki z niejawnym blokowaniem (za pomocą kolejki blokującej). Poza tym, ile wejść może twój aktor? jeśli jest tylko jeden (aktorzy scala i akka), powinieneś oddzielnie wymienić aktorów z wieloma wejściami. Jeśli aktorzy, o których mówisz, mogą mieć wiele wejść, wtedy nie ma różnicy między aktorami bezstanowymi i stanowymi (stan token przekazany do dodatkowego wkładu). –

+1

Lista była tylko osobistą opinią. Zmiany są uzasadnione, z wyjątkiem tego, że futures w żaden sposób nie implikuje wątków i wyraźnego blokowania. Skutki futures bez efektów ubocznych efektywnie modelują zmienne przepływu danych i zyskują współbieżność bez dopuszczania niedeterminizmu. –

+0

Futures w Javie (java.util.concurrent.Future) iw większości innych języków (patrz http://en.wikipedia.org/wiki/Futures_and_promises) blokują, a więc sugerują wątki. O jakich futures mówisz? –

0

Mam tendencję do myślenia, że ​​aktorzy są przydatni, gdy masz interakcje z wątkami. W twoim przypadku wydaje się, że wszystkie prace są niezależne; Używałbym futures.

+1

Czytanie innych odpowiedzi, myślę, że nowy powinien być nieco bardziej dopracowany. – manuell

Powiązane problemy