Pregunta

Estoy utilizando el siguiente enfoque spinlock:

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

setHasPerformedAction(false);

return getActionPerfomed();

Esto, básicamente, espera a que un usuario realice una acción y luego lo devuelve. Actualmente algo solicita una respuesta del usuario antes de continuar, es por esto que esperar hasta que se recibe de entrada. Sin embargo, me pregunto si esto es ineficiente y si estamos a la espera durante un tiempo (es decir, <= 30 seg) va a ralentizar el PC que ejecuta esta aplicación. ¿Hay otras alternativas que utilizan este enfoque es decir, cerraduras, semáforos si es así cuál es la sintaxis?

Gracias,

Aly

¿Fue útil?

Solución

De hecho, no sólo es ineficiente, sino que ni siquiera se garantiza que funcione, ya que no hay "sucede antes" de punta en el código que se está mostrando. Para crear un sucede antes borde que tiene que hacer uno de:

  1. acceder a una variable volátil
  2. Sincronizar en un recurso compartido
  3. Uso de un bloqueo utils concurrentes.

Como se ha mencionado en otro comentario, el más fácil solución, es simplemente para asegurarse de que su bandera es una variable volátil y lanzar simplemente un corto sueño en su bucle.

Sin embargo, la mejor cosa a hacer sería para sincronizar / espera / notificar en una variable compartida.

Los métodos que necesite para leer sobre son esperar y notificar . Para una mejor descripción sobre cómo utilizar estos, lee este artículo . Un fragmento de código ejemplo se muestra a continuación;

Thread 1

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

rosca 2

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

Otros consejos

Lo que has escrito se denomina bucle ocupado, que nunca se debe hacer.

Es posible que desee seguir haciendo eso, pero al menos el sueño un poco como para no ser bucle ocupado, que todavía no sería tan grande:

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

Otra forma de hacerlo sería poner en cola a las acciones del usuario en una cola de bloqueo: a continuación, simplemente podría estar utilizando un queue.take y la aplicación de cola se haría cargo de la edición para usted <. / p>

Y otra manera sería utilizar una devolución de llamada a ser notificado de las acciones del usuario.

Los tutoriales Java tienen una lección bien en concurrencia en Java:

http://java.sun.com/docs/books/ tutorial / esencial / concurrencia /

Si se van a modificar la interfaz de usuario desde otro hilo, tendrá que acordarse de hacer:

SwingUtils.invokeLater(actionToInvoke);

Hay un gui en sus etiquetas, por lo que voy a suponer que la acción se realiza en la interfaz gráfica de usuario.

La forma "recomendada" para hacer este tipo de cosas es que el hilo principal para ponerse a dormir (tal vez usando wait()) y para la acción GUI para notify() de nuevo en la vigilia vez que la acción se ha realizado.

Hay algunas clases para que, en java.util.concurrent.locks. Echar un vistazo a la clase LockSupport

Saludos Mike

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top