5

Tutaj używam strumienia Javaparallel do iterowania listy i wywoływania wywołania REST z każdym elementem listy jako danych wejściowych. Muszę dodać wszystkie wyniki wywołania REST do kolekcji, dla której używam ArrayList. Kod podany poniżej działa dobrze, z wyjątkiem tego, że niezwiązane z wątkami bezpieczeństwo tablicy ArrayList spowodowałoby niepoprawne wyniki, a dodanie wymaganej synchronizacji spowodowałoby rywalizację, podważając korzyść równoległości.Java 8 parallelStream dla współbieżnej bazy danych/wywołania REST

Czy ktoś może zaproponować mi odpowiedni sposób wykorzystania równoległego strumienia w mojej sprawie.

public void myMethod() { 
    List<List<String>> partitions = getInputData(); 
    final List<String> allResult = new ArrayList<String>(); 
    partitions.parallelStream().forEach(serverList -> callRestAPI(serverList, allResult); 
} 

private void callRestAPI(List<String> serverList, List<String> allResult) { 
    List<String> result = //Do a REST call. 
    allResult.addAll(result); 
} 

Odpowiedz

6

można zrobić operację z map zamiast forEach - które zagwarantuje bezpieczeństwo wątków (i jest odkurzacz z funkcjonalnego punktu widzenia programowania):

List<String> allResult = partitions.parallelStream() 
      .map(this::callRestAPI) 
      .flatMap(List::stream) //flattens the lists 
      .collect(toList()); 

A twój callRestAPI method:

private void callRestAPI(List<String> serverList) { 
    List<String> result = //Do a REST call. 
    return result; 
} 
+2

Myślę, że w szczególności aspekt * funkcjonalny * jest pouczający –

+0

Nie powinien ostatnią linią być '.collect (Collectors.toList());' – Zeeshan

+2

Założyłem 'import static java.util.stream.Collectors.toList ; '... – assylias

2

Nie wahałbym się przed synchronizowaniem dostępu do twojego ArrayList. Biorąc pod uwagę, że uzyskujesz dostęp do usługi zdalnej przez Rest, podejrzewam, że koszt synchronizacji będzie wynosił bez znaczenia:. Zmierzyłbym efekt zanim poświęcisz czas na optymalizację.

+1

downvoted dlaczego ? –