Frage

In meinem SWT Java App möchte ich oft Informationen zurück aus dem Inneren eines Display.syncExec () -Aufruf. Der beste Weg, die ich gefunden habe, so weit dies zu tun ist:

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)) { /* ... */ }

Ich denke, das ist erlaubt, da Arraylist Thread-sicher ist, aber gibt es einen besseren Behälter wir verwenden sollen, oder ein einfacherer Weg, zusammen?

War es hilfreich?

Lösung

ArrayList ist nicht Thread-sicher . Sie können eine Thread-sichere List mit Collections.synchronizedList . Es ist jedoch viel einfacher, einen AtomicInteger in Ihrem Fall oder AtomicReference in einem allgemeineren Fall zu verwenden.

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()) { /* ... */ }

Andere Tipps

ich in Angriff genommen nur dieses Problems und mein erster Versuch war ähnlich - Array oder eine Liste der gewünschten Art Gegenstände. Aber nach einer Weile habe ich so etwas wie dies oben:

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

Es ist viel aufgeräumter und entfernt redundante Variablen.

BTW. Mein wirklich erster Versuch war UIThreadRunnable zu verwenden, aber ich habe nicht SWTBot Abhängigkeit wollte, so ließ ich diese Lösung. Nachdem ich meine eigene Lösung gemacht fand ich heraus, verwenden sie um eine ähnliche Arbeit da drin.

Arraylist ist nicht Thread-sicher. Aus den entsprechenden Javadoc :

  

Beachten Sie, dass diese Implementierung nicht   synchronisiert. Wenn mehrere Threads   Zugriff auf eine Arraylist-Instanz   gleichzeitig, und mindestens eine der   Threads ändert die Liste   strukturell, muss synchronisiert werden   nach außen.

Wenn Sie eine Thread-sichere Durchführung der Liste benötigen, gibt es (mindestens) zwei im JDK bereitgestellt. CopyOnWriteArrayList und Vector

Sie können einen Integer [1] Array verwenden, um es übersichtlicher zu machen, aber ich glaube nicht, dass direkt eine nicht endgültige Variable aus dem Innern einer anonymen inneren Klasse aktualisieren.

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

Ich dachte, dass Sie die Ergebnisse als endgültig erklären musste (aber diese Änderung würde der Code nicht beeinflussen). Da der aktuellen Thread blockiert, bis das innere Thema ist ich fertig glaube nicht, Sie Synchronisation kümmern müssen (aber Sie müssen möglicherweise die Variable machen verletzen, so dass Sie sehen das Ergebnis).

Wenn dies oft geschieht, besser Sie verwenden subscribe / notify Modell zwischen Prozess und Aussicht. Ihre Ansicht abonniert hat das Ereignis, das die Nachricht Feld auslösen soll und wird benachrichtigt, wenn die Bedingungen erfüllt werden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top