Question

J'ai une fonction qui doit perfom deux opérations, l'une qui se termine rapidement et qui prend beaucoup de temps à courir. Je veux être en mesure de déléguer le fonctionnement à long en cours d'exécution à un fil et je ne me soucie quand la fin du thread, mais les fils doit remplir. Je mis en œuvre ce comme indiqué ci-dessous, mais, mon secondoperation ne se fait que les sorties de fonction après l'appel démarrage (). Comment puis-je faire en sorte que la fonction retourne, mais le second fil d'opération termine son exécution aussi bien et ne dépend pas du thread parent?

public void someFunction(String data)
{
   smallOperation()
   SecondOperation a = new SecondOperation();
   Thread th = new Thread(a);
   th.Start();
}

class SecondOperation implements Runnable
{
  public void run(){
  // doSomething long running
 }
} 
Était-ce utile?

La solution

public void someFunction(final String data) {
    shortOperation(data);
    new Thread(new Runnable() {
        public void run(){
            longOperation(data);
        }
    }).start();
}

Si someFunction est appelée, la machine virtuelle Java exécutera le longOperation si

  1. le fil conducteur n'est pas marqué comme démon (dans le code au-dessus n'est pas)
  2. le longOperation() ne jette pas une exception et
  3. pas d'appels à System.exit () est fait dans longOperation()

Autres conseils

La machine virtuelle Java ne sortira pas avant le fil se termine de. Ce code que vous ne compile même posté pas; peut-être le problème est dans votre code actuel.

Si votre deuxième fonction ne se fait pas, il n'a rien à voir avec votre fonction de retour. Si les appels quelque chose System.exit() ou si votre fonction lance une exception, le fil s'arrête. Dans le cas contraire, il fonctionnera jusqu'à ce qu'il soit terminé, même si votre principale cesse de fil. Cela peut être évité en définissant le nouveau thread pour être un démon, mais vous ne faites pas ici.

Solution en utilisant moderne Java

public void someFunction(String data) {
    smallOperation();
    new Thread(() -> {
        // doSomething long running
    }).start();
}

Il est peut-être tard pour répondre à cette question, mais voici la solution de travail. Il suffit d'ajouter les runnables à ExecutorService.

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

ExecutorService executor = Executors.newFixedThreadPool(10);
        executor.execute(new Runnable() {
            @Override
            public void run() {
                //your code
            }
        });

si je reçois votre droit de question, vous voulez invoquez someFunction(), exécutez court smallOperation(), exécutez un fil à la SecondOperation et assurez-vous que lors du retour de cette fonction, le SecondOperation est terminée.

si le débit i proposé est correct, u besoin d'ajouter que la ligne suivante:

public void someFunction(String data)
{
   smallOperation()
   SecondOperation a = new SecondOperation();
   Thread th = new Thread(a);
   th.Start();
   th.join(); //add this line to make your MainThread await for this to finish . 
}

class SecondOperation implements Runnable
{
  public void run(){
  // doSomething long running
 }
} 

jeter un oeil à cette article , il stipule que « Lorsque nous invoquons la méthode join sur un fil, le fil d'appel () passe dans un état d'attente. Il reste dans un état d'attente jusqu'à ce que se termine de fil référencé ». que je pense ce que vous essayez d'accomplir

si son pas le cas et que vous voulez être averti lorsque les SecondOperation se termine de, je vous suggère d'utiliser

Vous créez un véritable fil asynchrone en créant un second fil dans un fil temporaire.

(new Thread(new Runnable() { public void run() {
    (new Thread(new Runnable() { public void run()
    {
        /* async thread */
    }})).start();
}})).start();
scroll top