2010-05-10 12 views
1

Existe-t-il une manière plus élégante de faire ce que je fais ci-dessous? Autrement dit, existe-t-il un moyen plus élégant que l'interrogation et le sommeil, l'interrogation et le sommeil, et ainsi de suite pour savoir quand une méthode Runnable.run() a été appelée via invokeLater()?En attente de l'appel de invokeLater()

private int myMethod() { 
    final WaitForEventQueue waitForQueue = new WaitForEventQueue(); 
    EventQueue.invokeLater(waitForQueue); 
    while (!waitForQueue.done) { 
     try { 
      Thread.sleep(10); 
     } catch (InterruptedException ignore) { 
     } 
    } 

    return 0; 
} 

private class WaitForEventQueue implements Runnable { 
    private boolean done; 

    public void run() { 
     // Let all Swing text stuff finish. 
     done = true; 
    } 
} 
+0

Pour ce que ça vaut ce code échoue sur deux niveaux: (1) il est thread-safe pas parce que le fil d'attente ne peut jamais « voir » la mise à jour 'done' (voir le modèle mémoire de Java pour V5 +) et (2) l'interrogation est généralement une mauvaise solution, en particulier dans un langage qui a un mécanisme d'attente/notification si facile (voir Object.wait, et al). –

Répondre

2

Si vous voulez attendre, pourquoi ne pas appeler invokeAndWait plutôt que de mettre en œuvre vous-même?

+0

Parce que invokeAndWait provoque des blocages et des livelocks et mange essentiellement des chatons pour le petit-déjeuner. – Trejkaz

+0

@Trejkaz, pas vraiment mon expérience, mais je suis sûr que le code suggéré ne serait pas une amélioration. – Yishai

+0

Probablement pas, bien que je me demande. Parce qu'il n'utilise pas de verrou, peut-être qu'il ne sera pas bloquant. Cependant, je pense qu'il présentera cet autre problème où il n'est pas dans l'impasse, mais ne revient jamais. – Trejkaz

0

Au lieu d'attendre le fil pour finir, pourquoi ne pas simplement avoir l'interface utilisateur affiche une fileuse ou quelque chose, et que le fil appelle un événement quand il est fait.

+0

Salut Justin, Merci pour la suggestion, mais pourriez-vous être plus précis (à savoir montrer un exemple de code) dans la mesure où le « appel de fil [ant] un événement quand il est fait » partie? –

5

Une meilleure façon serait d'utiliser un FutureTask (qui implémente Runnable et Future) et de surcharger son événement done() pour faire quelque chose lorsque vous avez terminé.

De même, démarrez-le en tant que thread distinct (ou utilisez un Executor) s'il ne manipule pas l'interface graphique, plutôt que d'utiliser AWT EventQueue.