web-dev-qa-db-fra.com

Exécution simultanée de deux tâches indépendantes à l'aide de threads

J'ai étudié de nombreux tutoriels sur les discussions en Java, mais je ne parviens pas à trouver ma réponse.

Ma question est la suivante: comment exécuter deux threads indépendants simultanément?

Mon cas est le suivant: j'ai deux tâches;

  1. sauvegarder des données dans la base de données
  2. envoyer une notification Push sur un appareil mobile.

Puisque ces deux tâches sont indépendantes, je veux les exécuter simultanément.

J'ai essayé d'utiliser un pool de threads avec deux threads, mais le problème est que les tâches de base de données se terminent rapidement, mais l'envoi d'une notification Push prend un certain temps.

Par conséquent, lorsqu'une tâche est terminée pendant que l'autre est en attente, une exception est levée.

De plus, il n'y a pas de problème dans mon code car il fonctionne correctement sans utiliser de threads.

Merci d'avance

10
S1LENT WARRIOR
new Thread(new Runnable() {
    public void run() {
        System.out.println("Look ma, no hands");
    }
}).start();

new Thread(new Runnable() {
    public void run() {
        System.out.println("Look at me, look at me...");
    }
}).start();

Fonctionne très bien ...

Je préférerais utiliser un ExecutorService personnellement.

UPDATED avec l'exemple ExecutorService

Alors j'ai écrit cet exemple très rapide ...

Fondamentalement, il utilise ExecutorService pour exécuter quelques tâches simples. À l'heure actuelle, les deux tâches seront exécutées en parallèle (simultanément).

public static void main(String[] args) throws InterruptedException {
    ExecutorService service = Executors.newFixedThreadPool(2);
    service.submit(new PathScanner());
    service.submit(new Counter());

    service.shutdown();
    service.awaitTermination(1, TimeUnit.DAYS);

    System.exit(0);
}

public static class PathScanner implements Callable<Object> {

    @Override
    public Object call() throws Exception {
        scan(new File("C:/"), 0);
        return null;
    }

    protected void scan(File path, int deepth) {
        if (deepth < 15) {
            System.out.println("Scanning " + path + " at a deepth of " + deepth);

            File[] files = path.listFiles();
            for (File file : files) {
                if (file.isDirectory()) {
                    scan(file, ++deepth);
                }
            }
        }
    }
}

public static class Counter implements Callable<Object> {

    @Override
    public Object call() throws Exception {
        for (int index = 0; index < 1000; index++) {
            Thread.sleep(1);
            System.out.println(index);
        }
        return null;
    }
}

Exécuter...

Maintenant, changez ExecutorService service = Executors.newFixedThreadPool(2); en ExecutorService service = Executors.newFixedThreadPool(1); et exécutez-le à nouveau. Avez-vous vu la différence?

C'est le moyen de contrôler le nombre de threads simultanément que l'exécuteur peut utiliser pendant le traitement de sa file d'attente.

Créez quelques tâches supplémentaires, ajoutez-les à la file d'attente et voyez ce que vous obtenez.

31
MadProgrammer

J'avais un cas d'utilisation pour rechercher le fichier dans plusieurs dossiers en utilisant multithreading. En entrée, je n'avais que le chemin du répertoire racine et il pouvait y avoir un nombre quelconque de répertoires enfants. Hypothèse - Le fichier sera toujours disponible uniquement dans l'un des répertoires enfants.

import Java.io.File;
import Java.io.FileFilter;
import Java.util.concurrent.ExecutorService;
import Java.util.concurrent.Executors;

public class SearchFile implements Runnable {

    private String dirPath = null;

    public SearchFile() {

    }

    public SearchFile(String dirPath) {
        this.dirPath = dirPath;
    }

    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();
        File dir = new File("D://");
        checkRootDirectory(dir);
        long endTime = System.currentTimeMillis();
        System.out.println("Time taken: "+(endTime - startTime) + "ms");
    }

    private static void checkRootDirectory(File root) {
        File[] list = root.listFiles(new FileFilter() {

            @Override
            public boolean accept(File pathname) {
                return pathname.isDirectory() && !pathname.isHidden();
            }
        });

        ExecutorService service = Executors.newFixedThreadPool(list.length);
        for (File directories : list) {
            String dirPath = directories.getAbsolutePath();
            Thread thread = new Thread(new SearchFile(dirPath));
            service.execute(thread);
        }
        service.shutdown();
        while(!service.isTerminated()) {

        }
    }

    @Override
    public void run() {
        checkEachDirectory(new File(dirPath), "Temp.txt");
    }

    private void checkEachDirectory(File root, String fileName) {
        File[] list = root.listFiles();
        if (null != list) {
            for (File dir : list) {
                if (dir.isDirectory()) {
                    checkEachDirectory(dir, fileName);
                } else if (fileName.equalsIgnoreCase(dir.getName())) {
                    System.out.println(
                            "Thread name: " + Thread.currentThread().getName() + " Founded @" + dir.getAbsolutePath());
                }
            }
        }
    }
}
1
Gopal Aggarwal