Frage

Ich bin mit dem folgenden spinlock Ansatz:

while(!hasPerformedAction()){
    //wait for the user to perform the action
    //can add timer here too
}

setHasPerformedAction(false);

return getActionPerfomed();

Dieses wartet im Grunde für einen Benutzer eine Aktion auszuführen, und gibt sie dann. etwas fordert zur Zeit eine Antwort von dem Benutzer, bevor Sie fortfahren, das ist, warum ich warten, bis der Eingang empfangen wird. Allerdings habe ich mich gefragt, ob dies ineffizient ist und wenn wir eine Weile warten (d <= 30 Sekunden) wird es den PC verlangsamen, die diese App läuft. Gibt es noch andere Alternativen mit diesem Ansatz das heißt Schlösser, Semaphore wenn ja, was ist die Syntax?

Danke,

Aly

War es hilfreich?

Lösung

In der Tat, nicht nur diese ineffizient ist, wird es nicht einmal zur Arbeit gewährleistet, da es keine „passiert-vor“ Kante in dem Code, den Sie zeigt. So erstellen Sie ein passiert-vor Rand braucht man von dem zu tun:

  1. Zugriff auf eine volatile Variable
  2. Synchronisieren auf eine gemeinsam genutzte Ressource
  3. verwenden, um eine gleichzeitige utils sperren.

Wie in einem anderen Kommentar erwähnte, ist die am einfachsten Lösung, einfach ist es, sicherzustellen, dass Ihre Flagge eine flüchtige Variable ist, und einfach einen kurzen Schlaf in der Schleife werfen.

Doch das Beste, was zu tun wäre, synchronize / wait / notify auf einem gemeinsam genutzten Variable.

Die Methoden, die Sie auf lesen sind warten und benachrichtigen . Für eine bessere Beschreibung, wie diese verwenden, lesen Sie diesem Artikel . Ein Beispiel-Code-Snippet ist unten dargestellt;

Thema 1

Object shared = new Object();
startThread2(shared);
synchronized (shared) {
  while (taskNotDone())
    shared.wait();
}

Gewinde 2

// shared was saved at the start of the thread
// do some stuff
markTaskAsDone();
synchronized (shared) {
  shared.notify();
}

Andere Tipps

Was Sie geschrieben haben, ist damit beschäftigt Looping genannt, was sollten Sie nie tun.

Sie können möchten, dass halten tun, aber zumindest ein bisschen Schlaf als nicht beschäftigt Looping sein, die noch nicht so groß sein würden:

while( !hasPerformedAction() ) {
    (sleep a bit here)
}

Eine andere Möglichkeit, es zu tun, würde die Benutzeraktionen auf einer Sperr Warteschlange einzureihen: dann könnte man einfach ein queue.take und die Warteschlange Implementierung verwenden würde Pflege des Problems nehmen Sie <. / p>

Und eine weitere Möglichkeit, einen Rückruf zu verwenden, wäre der Benutzeraktionen informiert werden.

Die Java-Tutorials haben eine gute Lektion auf Gleichzeitigkeit in Java:

http://java.sun.com/docs/books/ tutorial / essential / concurrency /

Wenn Sie UI von einem anderen Thread gehen zu ändern, werden Sie wollen, daran zu erinnern, zu tun:

SwingUtils.invokeLater(actionToInvoke);

Es gibt ein gui in Ihren Tags, so dass ich davon ausgehen werde, dass die Aktion in der GUI durchgeführt wird.

Der „empfehlenswert“ Weg, um diese Art der Sache zu tun ist, für den Haupt-Thread selbst in dem Schlaf zu setzen (vielleicht mit wait()) und für die GUI-Aktion, um notify() wieder in Wachheit, wenn die Aktion durchgeführt wurde.

Es gibt einige Klassen für die in java.util.concurrent.locks. Hier finden Sie aktuelle Klasse LockSupport

Viele Grüße Mike

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