Domanda

Sto usando il seguente approccio spinlock:

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

setHasPerformedAction(false);

return getActionPerfomed();

questo attende fondamentalmente per un utente di eseguire un'azione e poi lo restituisce. Attualmente qualcosa richiede una risposta da parte dell'utente prima di continuare, questo è il motivo per cui mi aspetto che viene ricevuto in ingresso. Tuttavia mi chiedevo se questo è inefficiente e se siamo in attesa per un po '(vale a dire <= 30 sec) si è rallentare il pc che esegue questa applicazione. Ci sono altre alternative che utilizzano questo approccio cioè serrature, semafori in caso affermativo qual è la sintassi?

Grazie,

Aly

È stato utile?

Soluzione

In realtà, non solo è inefficiente, non è nemmeno garantito per funzionare, in quanto non v'è alcuna "accade-prima" bordo nel codice che si sta mostrando. Per creare un accade-prima bordo hai bisogno di fare uno dei seguenti:

  1. Accedere a una variabile volatile,
  2. Sincronizza su una risorsa condivisa
  3. Utilizzare un utils simultanei blocco.

Come accennato in un altro commento, semplice soluzione, è semplicemente quello di garantire che la vostra bandiera è una variabile volatile, e semplicemente gettare un breve sonno nel vostro ciclo.

Tuttavia, la cosa migliore da fare sarebbe quella di sincronizzare / wait / notify su una variabile condivisa.

I metodi che avete bisogno di leggere su sono attendere e notificare . Per una migliore descrizione su come utilizzare questi, leggere questo articolo . Un frammento di codice di esempio è mostrato sotto;

Thread 1

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

Thread 2

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

Altri suggerimenti

Quello che hai scritto è chiamato looping occupato, che non si dovrebbe mai fare.

Si consiglia di continuare a farlo, ma almeno un po 'il sonno per non essere looping occupato, che ancora non sarebbe quella grande:

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

Un altro modo per farlo sarebbe di accodare le azioni dell'utente su una coda di blocco: allora si può semplicemente utilizzare un queue.take e l'implementazione di coda si sarebbe preso cura del problema per voi <. / p>

E un altro modo sarebbe quello di utilizzare un callback per essere notificati delle azioni dell'utente.

I tutorial Java hanno una lezione di buon sulla concorrenza in Java:

http://java.sun.com/docs/books/ tutorial / essenziali / concorrenza /

Se avete intenzione di essere la modifica dell'interfaccia utente da un altro thread, vi verrà voglia di ricordarsi di fare:

SwingUtils.invokeLater(actionToInvoke);

C'è un gui in tag, quindi darò per scontato che l'azione viene eseguita nella GUI.

Il modo "raccomandato" per fare questo genere di cose è per il filo conduttore di mettersi a dormire (forse usando wait()) e per l'azione GUI per notify() di nuovo in stato di veglia, una volta è stata eseguita l'azione.

Ci sono alcune classi per quella in java.util.concurrent.locks. Dai un'occhiata alla Classe LockSupport

Saluti Mike

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top