Question

Dans mon application Java SWT, je souhaite souvent renvoyer des informations à partir d'un appel Display.syncExec (). La meilleure façon que j’ai trouvée jusqu’à présent de procéder est la suivante:

final ArrayList<Integer> result = new ArrayList<Integer>();
GUI.display().syncExec(new Runnable(){ public void run() {
   MessageBox mb = /* ... */;
    /* set up messagebox */
   result.add(mb.open());
}});
if (SWT.OK == result.get(0)) { /* ... */ }

Je pense que cela est autorisé car ArrayList est thread-safe, mais y a-t-il un meilleur conteneur que je devrais utiliser, ou un moyen plus simple tout à fait?

Était-ce utile?

La solution

ArrayList est pas adapté aux threads . Vous pouvez obtenir une liste sécurisée pour les threads avec Collections.synchronizedList . Cependant, il est beaucoup plus simple d’utiliser un AtomicInteger dans votre cas ou un AtomicReference dans un cas plus général.

final AtomicInteger resultAtomicInteger = new AtomicInteger();
Display.getCurrent().syncExec(new Runnable() { 
    public void run() {
        MessageBox mb = /* ... */;
            /* set up messagebox */
        resultAtomicInteger.set(mb.open());
}});
if (SWT.OK == resultAtomicInteger.get()) { /* ... */ }

Autres conseils

Je viens d’aborder ce problème et mon premier essai a été similaire - tableau ou liste des éléments de type souhaités. Mais après un moment, j'ai inventé quelque chose comme ceci:

abstract class MyRunnable<T> implements Runnable{
    T result;
}
MyRunnable<Integer> runBlock = new MyRunnable<Integer>(){
   MessageBox mb = /* ... */;
    /* set up messagebox */
   result = mb.open();
}
GUI.display().syncExec(runBlock);
runBlock.result; //holds a result Integer

Il est beaucoup plus ordonné et supprime les variables redondantes.

BTW. Mon premier essai a été d'utiliser UIThreadRunnable, mais je ne voulais pas de dépendance à SWTBot, j'ai donc abandonné cette solution. Après avoir mis au point ma propre solution, j'ai découvert qu'ils utilisaient un travail similaire.

ArrayList n'est pas thread-safe. Javadoc approprié:

  

Notez que cette implémentation n'est pas   synchronisé. Si plusieurs threads   accéder à une instance ArrayList   simultanément, et au moins un des   les discussions modifient la liste   structurellement, il doit être synchronisé   à l'extérieur.

Si vous avez besoin d'une implémentation thread-safe de List, il en existe (au moins) deux dans le JDK: CopyOnWriteArrayList et Vector.

Vous pouvez utiliser un tableau Integer [1] pour le rendre plus concis, mais je ne pense pas qu'il puisse directement mettre à jour une variable non finale à partir d'une classe interne anonyme.

final Integer[] result = new Integer[1];

Je pensais que vous deviez déclarer les résultats comme finaux (mais cette modification n’affecterait pas votre code). Étant donné que le thread actuel est bloqué jusqu'à ce que le thread interne soit terminé, je ne pense pas que vous ayez à vous soucier de la synchronisation (mais vous devrez peut-être aussi violer la variable pour que le résultat soit visible).

Si cela se produit souvent, vous feriez mieux d'utiliser le modèle subscribe / notify entre votre processus et votre vue. Votre vue est abonnée à l'événement qui devrait déclencher cette boîte de message et être notifiée lorsque les conditions sont remplies.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top