138 votes

Comment faire attendre pour un autre thread un thread en Java ' s sortie ?

Je suis en train de faire une application Java avec une application à la logique de fil et d'une base de données-access-fil. Deux d'entre eux persistent pendant toute la durée de vie de l'application. Cependant, j'ai besoin de vous assurer que l'application thread attend jusqu'à ce que le db fil est prêt (actuellement en appelant dbthread.isReady()). Je ne me dérangerait pas si l'application thread bloqué jusqu'à ce que le db fil était prêt.

Thread.join() ne ressemble pas à une solution - la db fil des sorties en application de l'arrêt.

while (!dbthread.isReady()) {} type de travaux, mais le vide boucle consomme beaucoup de cycles de processeur.

D'autres idées? Merci.

150voto

pdeva Points 4597

Utiliser un CountDownLatch avec un compteur de 1.

Maintenant dans l’app fil-

Dans le fil de la db, après que vous êtes fait, do-

133voto

Herman Lintvelt Points 1171

Je voudrais vraiment vous recommandons de passer par un tutoriel comme Java de Sun Simultanéité avant de commencer dans le monde magique de multithreading.

Il y a également un certain nombre de bons livres (google pour "Programmation Concurrente en Java", "la Java de la Simultanéité dans la Pratique".

Pour accéder à votre réponse:

Dans votre code qui doit attendre l' dbThread, vous devez avoir quelque chose comme ceci:

//do some work
synchronized(objectYouNeedToLockOn){
    while (!dbThread.isReady()){
        objectYouNeedToLockOn.wait();
    }
}
//continue with work after dbThread is ready

Dans votre dbThreads'méthode, vous aurez besoin de faire quelque chose comme ceci:

//do db work
synchronized(objectYouNeedToLockOn){
    //set ready flag to true (so isReady returns true)
    ready = true;
    objectYouNeedToLockOn.notifyAll();
}
//end thread run method here

L' objectYouNeedToLockOn je suis à l'aide de ces exemples est de préférence de l'objet que vous avez besoin de manipuler simultanément à partir de chaque thread, ou vous pouvez créer un distinct Object (je ne recommanderais pas faire les méthodes elles-mêmes synchronisé):

private final Object lock = new Object();
//now use lock in your synchronized blocks

Pour approfondir vos connaissances:
Il y a d'autres (parfois mieux) façons de le faire ci-dessus, par ex. avec de l' CountdownLatches, etc. Depuis Java 5, il y a beaucoup de chouettes simultanéité des classes dans l' java.util.concurrent forfait et sous-packages. Vous avez vraiment besoin de trouver des documents en ligne pour connaître la simultanéité, ou d'obtenir un bon livre.

27voto

Ash Points 626

Exigence ::

  1. Attendre l'exécution de la prochaine thread jusqu'à ce que précédent terminé.
  2. Prochain thread ne doit pas commencer jusqu'à ce thread précédent s'arrête, quel que soit le moment de la consommation.
  3. Il doit être simple et facile à utiliser.

Réponse ::

@See java.util.de façon concomitante.L'avenir.get() doc.

l'avenir.get() Attend si nécessaires pour le calcul à effectuer, puis récupère son résultat.

Travail Réalisé!! Voir l'exemple ci-dessous

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

import org.junit.Test;

public class ThreadTest {

    public void print(String m) {
        System.out.println(m);
    }

    public class One implements Callable<Integer> {

        public Integer call() throws Exception {
            print("One...");
            Thread.sleep(6000);
            print("One!!");
            return 100;
        }
    }

    public class Two implements Callable<String> {

        public String call() throws Exception {
            print("Two...");
            Thread.sleep(1000);
            print("Two!!");
            return "Done";
        }
    }

    public class Three implements Callable<Boolean> {

        public Boolean call() throws Exception {
            print("Three...");
            Thread.sleep(2000);
            print("Three!!");
            return true;
        }
    }

    /**
     * @See java.util.concurrent.Future.get() doc
     *      <p>
     *      Waits if necessary for the computation to complete, and then
     *      retrieves its result.
     */
    @Test
    public void poolRun() throws InterruptedException, ExecutionException {
        int n = 3;
        // Build a fixed number of thread pool
        ExecutorService pool = Executors.newFixedThreadPool(n);
        // Wait until One finishes it's task.
        pool.submit(new One()).get();
        // Wait until Two finishes it's task.
        pool.submit(new Two()).get();
        // Wait until Three finishes it's task.
        pool.submit(new Three()).get();
        pool.shutdown();
    }
}

La sortie de ce programme ::

              One...
              One!!
              Two...
              Two!!
              Three...
              Three!!

Vous pouvez voir que prend 6sec, avant de terminer sa tâche, qui est plus grande que les autres fil. Donc L'Avenir.get() attend jusqu'à ce que la tâche est accomplie.

Si vous n'utilisez pas l'avenir.get() il n'attendez pas à la fin et s'exécute en fonction de la consommation le temps.

Bonne Chance avec Java simultanéité.

7voto

WMR Points 5869

Essayez le CountDownLatch hors classe de l' java.util.concurrent paquet, qui offre des niveaux plus élevés de synchronisation au niveau des mécanismes, qui sont beaucoup moins enclins à faire des erreurs que tout le faible niveau de stuff.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X