Question

J'utilise l'approche spinlock suivante:

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

setHasPerformedAction(false);

return getActionPerfomed();

attend essentiellement pour un utilisateur d'effectuer une action, puis retourne. À l'heure actuelle quelque chose demande une réponse de l'utilisateur avant de continuer, ce pourquoi j'attendre jusqu'à ce que l'entrée est reçue. Cependant, je me demandais si cela est inefficace et si nous attendons un certain temps (par exemple <= 30 secondes) sera ralentir le PC qui exécute cette application. Y at-il d'autres alternatives à l'aide de cette approche à savoir les verrous, sémaphores si oui, quelle est la syntaxe?

Merci,

Aly

Était-ce utile?

La solution

En fait, non seulement cette inefficacité, il est même pas garanti de fonctionner, car il n'y a pas de « arrive-avant » bord dans le code que vous montrez. Pour créer un arrive-avant bord que vous devez faire l'un des:

  1. accéder à une variable volatile
  2. Synchronisez sur une ressource partagée
  3. Utilisez un verrou utils simultanément.

Comme mentionné dans un autre commentaire, le plus facile solution, est tout simplement de faire en sorte que votre drapeau est une variable volatile, et simplement jeter un court sommeil dans votre boucle.

Cependant, la meilleure chose à faire serait de synchroniser / wait / notify sur une variable partagée.

Les méthodes que vous devez lire sur sont attendre et informer. Pour une meilleure description sur la façon de les utiliser, lisez cet article . Un extrait de code exemple est présenté ci-dessous;

Discussion 1

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

Discussion 2

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

Autres conseils

Qu'est-ce que vous avez écrit est appelé looping occupé, que vous ne devriez jamais faire.

Vous pouvez continuer à le faire, mais au moins dormir un peu pour ne pas être mise en boucle occupée, ce qui ne serait toujours pas ce grand:

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

Une autre façon de le faire serait de enqueue les actions de l'utilisateur sur une file d'attente de blocage: vous pouvez simplement utiliser un queue.take et la mise en œuvre de file d'attente se chargerait de la question pour vous <. / p>

Et une autre façon serait d'utiliser un rappel à notifier des actions de l'utilisateur.

Les tutoriels java ont une bonne leçon sur en java concurrency:

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

Si vous allez modifier l'interface utilisateur d'un autre thread, vous voulez vous rappeler de le faire:

SwingUtils.invokeLater(actionToInvoke);

Il y a un IUG dans vos balises, donc je suppose que l'action se fait dans l'interface graphique.

Le « recommandé » façon de faire ce genre de chose est le fil conducteur de se mettre à dormir (peut-être en utilisant wait()) et pour l'action de GUI pour notify() nouveau dans l'état de veille une fois l'action a été effectuée.

Il y a quelques classes pour que java.util.concurrent.locks. Jetez un oeil à LockSupport classe

Cordialement Mike

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