Question

Je suis assez naïf en ce qui concerne le monde du threading et de la concurrence Java. J'essaie actuellement d'apprendre. J'ai fait un exemple simple pour essayer de comprendre comment fonctionne la concurrence.

Voici mon code:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadedService {

    private ExecutorService exec;

    /**
     * @param delegate
     * @param poolSize
     */
    public ThreadedService(int poolSize) {
        if (poolSize < 1) {
            this.exec = Executors.newCachedThreadPool();
        } else {
            this.exec = Executors.newFixedThreadPool(poolSize);
        }
    }

    public void add(final String str) {
        exec.execute(new Runnable() {
            public void run() {
                System.out.println(str);
            }

        });

    }

    public static void main(String args[]) {
        ThreadedService t = new ThreadedService(25);
        for (int i = 0; i < 100; i++) {
            t.add("ADD: " + i);
        }
    }

}

Que dois-je faire pour que le code affiche les numéros 0 à 99 dans un ordre séquentiel?

Était-ce utile?

La solution

Les

Les pools de threads sont généralement utilisés pour des opérations ne nécessitant pas synchronisation ou sont fortement parallèle .

L’impression séquentielle des numéros 0 à 99 n’est pas un problème simultané et nécessite la synchronisation des threads pour éviter une impression dans l’ordre.

Je vous recommande de jeter un coup d'œil au cours sur les accès simultanés à Java . pour avoir une idée de la concurrence en Java.

Autres conseils

L’idée des threads est de ne pas faire les choses de manière séquentielle.

Vous aurez besoin d'un état partagé pour vous coordonner. Dans l'exemple, l'ajout de champs d'instance à votre classe externe fonctionnera dans cet exemple. Supprimer le paramètre de add. Ajouter un objet de verrouillage et un compteur. Saisissez le verrou, incrémentez le nombre, imprimez le nombre, incrémentez le numéro, relâchez le numéro.

La solution la plus simple à votre problème consiste à utiliser une taille de ThreadPool de 1. Cependant, ce n'est pas vraiment le genre de problème que l'on pourrait utiliser avec des threads.

Pour développer, si vous créez votre exécuteur avec:

this.exec = Executors.newSingleThreadExecutor();

alors vos threads seront tous planifiés et exécutés dans l'ordre dans lequel ils ont été soumis pour exécution. Il existe quelques scénarios où cela est une chose logique à faire, mais dans la plupart des cas, les threads ne sont pas le bon outil à utiliser pour résoudre ce problème.

Ce genre de chose a du sens à faire lorsque vous devez exécuter la tâche dans un autre thread - cela prend peut-être beaucoup de temps et vous ne voulez pas bloquer un thread d'interface graphique - mais vous ne le faites pas besoin ou ne veut pas que les tâches soumises soient exécutées en même temps.

Le problème est par définition non adapté aux threads. Les threads sont exécutés indépendamment et il n'y a pas vraiment de moyen de prédire quel thread est exécuté en premier.

Si vous souhaitez modifier votre code afin qu'il s'exécute de manière séquentielle, modifiez add to:

public void add(final String str) {
    System.out.println(str);
}

Vous n'utilisez pas de threads (pas le vôtre du moins) et tout se passe de manière séquentielle.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top