2017-10-19 6 views
0

Dans mon thread principal, j'envoie des données au serveur via HttpURLConnection, puis je démarre un timer pour exécuter un TimerTask périodiquement pour vérifier la réponse du serveur. Quand j'obtiens la chaîne attendue, j'appelle timer.cancel(). Après cela, le thread principal reprend à partir de l'endroit où le timer est démarré.Comment supprimer le thread principal jusqu'à ce qu'un thread TimerTask invoqué par le thread principal soit terminé?

J'imagine code suivant simplifié avec le même mécanisme juste pour ce poste:

public class Test { 
    public static void main(String[] args) throws InterruptedException { 
     System.out.println("start"); 
     Timer timer = new Timer(); 
     TmTask timerTask = new TmTask(timer);  
     Thread thread = new Thread(timerTask,"thread_1"); 
     thread.start(); 
     thread.join();  
     System.out.println("end"); 
    } 
} 

class TmTask extends TimerTask{ 
    Timer t; 

    public TmTask(Timer t){ 
     this.t = t; 
    } 

    @Override 
    public void run() { 
     t.schedule(new A(t), 100, 1000); 

    } 
} 
class A extends TimerTask{ 
    private Timer t; 
    private int i = 0; 
    public A(Timer t) { 
     this.t = t; 
    } 
    @Override 
    public void run() { 
     System.out.println("abc"); 
     i++; 
     if (i == 3) t.cancel(); 
    } 
} 

Mon expection est:

start 
abc 
abc 
abc 
end 

Mais je reçois:

start 
end 
abc 
abc 
abc 

Enfin, je réalise que dans mon code il y a 3 threads créés mais je m'attendais à 2 (thread principal et thread Timer), et le join() méthode fonctionne sur le thread nommé thread_1 au lieu du thread de minuterie. Mais je n'ai aucune idée de comment l'améliorer.

Quelqu'un peut-il m'aider? Merci d'avance.

+0

Pourquoi voulez-vous réutiliser le fil? Lorsque vous l'attendez dans le thread principal, vous pouvez simplement l'exécuter sur le thread principal ... – Lino

+0

Cela casserait l'idée d'un fil. Vous voulez utiliser des threads pour le travail asynchrone. Ce que vous voulez faire, c'est le forcer à être synchrone. –

+0

En aucun cas, une TimerTask ne doit contenir une référence à un Timer. La tâche * est * le travail de fond; il ne devrait pas * commencer * d'autres travaux de fond. – VGR

Répondre

1

Le but de la création d'un nouveau thread est de le démarrer séparément du thread principal pour obtenir une exécution parallèle. Vous avez 3 threads parce que le timertask crée son propre thread. Si vous voulez que votre thread courant (principal) pour arrêter et attendre résultat alors vous pouvez juste faire quelque chose comme:

boolean result = false; 
while(! result) { 
result=checkForResult(); 
Thread.sleep(1000); 
} 

se met en pause le thread courant et l'amener à bloquer. Habituellement, pour de telles tâches externes et des appels asynchrones, vous ne voulez pas que le thread principal arrête l'exécution et attendez parce que vous ne savez pas quand vous obtiendrez le résultat et il peut attendre indéfiniment. Alors, probablement, votre résultat est le résultat souhaité? :)

+0

Je voudrais juste suggérer de lancer l'idée avec l'attente, et juste exécuter tout sur le fil principal, ou est-ce que je pense mal? – Lino

+0

Ouais c'est ce que j'essaie de dire. Si vous voulez que votre thread principal attende, vous n'avez pas besoin de threads supplémentaires. L'idée des threads est d'exécuter quelque chose en parallèle au thread principal. –

+0

Mais pour bloquer des tâches en cours d'exécution en parallèle et ne pas attendre peut être le bon choix - et alors ce qu'il a fait est bien et ce qu'il veut faire est faux;) –