-1
votes

Parallèle A pour boucle en Java

J'ai une boucle pour la boucle qui boucle sur une liste de collections. À l'intérieur de la boucle Certaines requêtes Select / Update ont lieu sur la collecte exclusive des autres collections. Étant donné que chaque collection a beaucoup de données à traiter sur je voudrais le paralléliser.

L'extrait de code ressemble à ceci: xxx

Comment puis-je atteindre cet objectif Java?


1 commentaires

Créez une piscine de fil et, pour chaque collection, soumettez un emploi.


3 Réponses :


2
votes

Vous pouvez utiliser le Parallelstream () Méthode (depuis Java 8): xxx pré>

Plus d'informations sur flux . p>


Une autre façon de le faire consiste à utiliser des exécuteurs: P>

    try
    {
        final ExecutorService exec = Executors.newFixedThreadPool(collections.size());
        for (final String collection : collections)
        {
            exec.submit(() -> {
                // Select queries on collection
                // Update queries on collection
            });
        }

        // We want to wait that the jobs are done.
        final boolean terminated = exec.awaitTermination(500, TimeUnit.MILLISECONDS);
        if (terminated == false)
        {
            exec.shutdownNow();
        }

    } catch (final InterruptedException e)
    {
        e.printStackTrace();
    }


3 commentaires

@Visgal à droite, cependant, considérez Cette réponse comme parallèletream peut ne pas Toujours la meilleure solution


pour (Collection finale Collection: Collections) Cette étape me donne une erreur: Type Mismatch: impossible de convertir de la chaîne de type d'élément à la collection


Ok, je pensais que vous utilisiez une liste de collection , Mon mauvais. Il suffit de remplacer par chaîne. J'ai édité le post.



2
votes
final int numberOfThreads = 32;

final ExecutorService executor = Executors.newFixedThreadPool(numberOfThreads);

// List to store the 'handles' (Futures) for all tasks:
final List<Future<MyResult>> futures = new ArrayList<>();

// Schedule one (parallel) task per String from "collections":
for(final String str : collections) {
  futures.add(executor.submit(() -> { return doSomethingWith(str); }));
}


// Wait until all tasks have completed:
for ( Future<MyResult> f : futures ) {
  MyResult aResult = f.get(); // Will block until the result of the task is available.
  // Optionally do something with the result...
}

executor.shutdown(); // Release the threads held by the executor.

// At this point all tasks have ended and we can continue as if they were all executed sequentially
Adjust the numberOfThreads as needed to achieve the best throughput. More threads will tend to utilize the local CPU better, but may cause more overhead at the remote end. To get good local CPU utilization, you want to have (much) more threads than CPUs (/cores) so that, whenever one thread has to wait, e.g. for a response from the DB, another thread can be switched in to execute on the CPU.

1 commentaires

Merci beaucoup, c'est une réponse très utile.



0
votes

Il y a un certain nombre de questions que vous devez vous demander de trouver la bonne réponse:

Si j'ai autant de threads que le nombre de mes cœurs de la CPU, cela suffirait-il?

Utilisation Parallelstream () vous donnera autant de threads que vos cœurs CPU.

paralléliser la boucle donnez-moi un coup de pouce de performance ou y a-t-il un goulot d'étranglement sur la DB?

Vous pouvez faire tourner 100 threads, traitement en parallèle, mais cela ne signifie pas que vous ferez les choses 100 fois plus rapides, si votre DB ou le réseau ne permettent pas de gérer le volume. Le verrouillage DB peut également être un problème ici.

Dois-je traiter mes données dans un ordre spécifique?

Si vous devez traiter vos données dans un ordre spécifique, cela peut limiter vos choix. Par exemple. foreach () ne garantit pas que les éléments de votre collection seront traités dans un ordre spécifique, mais foreachorded () fait (avec un coût de performance).

est ma source de données capable d'aller chercher des données de manière réactive?

Il y a des cas lorsque notre DataSource peut fournir des données sous la forme d'un flux. Dans ce cas, vous pouvez toujours traiter ce flux à l'aide d'une technologie telle que rxjava ou Webflux . Cela vous permettrait de prendre une approche différente de votre problème.

Après avoir dit tout ce qui précède, vous pouvez choisir l'approche que vous souhaitez (exécuteurs, rxjava, etc.) qui conviennent mieux à votre objectif.


0 commentaires