Consejos para evitar bloqueos en Java


Estoy estudiando subprocesos java y deadlocks, entiendo ejemplos de deadlock, pero me pregunto si hay reglas generales a seguir para evitarlo.

Mi pregunta es si hay reglas o consejos que se pueden aplicar al código fuente en Java para evitar bloqueos? En caso afirmativo, ¿podría explicar cómo implementarlo?

Author: djechlin, 2013-05-28

11 answers

Algunos consejos rápidos de mi cabeza

  • no use múltiples hilos (como lo hace Swing, por ejemplo, al ordenar que todo se haga en el EDT)
  • no sostenga varios bloqueos a la vez. Si lo hace, siempre adquiere las cerraduras en el mismo orden
  • no ejecute código extranjero mientras mantiene un bloqueo
  • use bloqueos interrumpibles
 26
Author: JB Nizet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-27 21:51:59

Encapsular, encapsular, encapsular! Probablemente el error más peligroso que puede cometer con las cerraduras es exponer su cerradura al mundo (hacerlo público). No se sabe lo que puede suceder si haces esto, ya que cualquiera podría adquirir el bloqueo sin que el objeto lo sepa (esta es también la razón por la que no debes bloquear this). Si mantiene su bloqueo privado, entonces tiene un control completo y esto lo hace más manejable.

 11
Author: Despertar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-28 03:57:43
  1. Evite los bloqueos utilizando estructuras de datos sin bloqueo (por ejemplo, use un ConcurrentLinkedQueue en lugar de un ArrayList sincronizado)
  2. Siempre adquirir las cerraduras en el mismo orden, por ejemplo, asignar un valor numérico único a cada cerradura y adquirir las cerraduras con menor valor numérico antes de adquirir las cerraduras con mayor valor numérico
  3. Libere sus bloqueos después de un período de tiempo de espera (técnicamente esto no evita los bloqueos, solo ayuda a resolverlos después de que hayan ocurrido)
 10
Author: Zim-Zam O'Pootertoot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-27 21:51:08

Leer y entender Java: Concurrencia y Práctica. Esto no se trata de "consejos" para evitar un punto muerto. Nunca contrataría a un desarrollador que supiera algunos consejos para evitar un callejón sin salida y, a menudo, evitaría un callejón sin salida. Se trata de entender la concurrencia. Afortunadamente, hay un libro completo de nivel intermedio sobre el tema, así que léalo.

 7
Author: djechlin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-10 21:49:39
  1. No use bloqueos.
  2. Si es necesario, mantenga sus cerraduras locales. Los bloqueos globales pueden ser muy complicados.
  3. Haga lo menos posible cuando mantenga la cerradura.
  4. Use franjas para bloquear solo segmentos de sus datos
  5. Prefieren tipos inmutables. Muchas veces esto significa copiar datos en lugar de compartir datos.
  6. Utilice comparar y establecer (CAS) mecánica en su lugar, Ver AtomicReference por ejemplo.
 6
Author: jontejj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-27 22:30:05

Dada una opción de diseño, use el paso de mensajes donde solo hay bloqueos en la cola push/pop. Esto no siempre es posible, pero, si lo es, tendrá muy pocos puntos muertos. Todavía puedes conseguirlos, pero tienes que esforzarte mucho :)

 4
Author: Martin James,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-28 00:29:09

Hay casi una gran regla cuando se trata de prevenir los estancamientos:

Si necesita tener varios bloqueos en su código, asegúrese de que todos los usuarios siempre los adquieran en el mismo orden.

Mantener su código libre de bloqueos debería ser casi siempre su objetivo. Puede intentar deshacerse de ellos mediante el uso de objetos inmutables o locales de hilo y estructuras de datos sin bloqueo.

 3
Author: Keppil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-27 21:51:01

Este es un ejemplo clásico de punto muerto:

public void methodA(){

  synchronized(lockA){
  //...

   synchronized(lockB){
   //...
  }
 }
}

public void methodB(){

  synchronized(lockB){
  //...

   synchronized(lockA){
   //...
   }
  }
}

Estos métodos probablemente crearían un gran punto muerto si son llamados por muchos hilos. Esto se debe a que los objetos están bloqueados en diferente orden. Esta es una de las razones más comunes de los bloqueos, por lo que si desea evitarlos, asegúrese de que los bloqueos se adquieran en orden.

 2
Author: Asier Aranbarri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-27 22:30:50
  1. Evite los bloqueos anidados. Esta es la razón más común de estancamiento. Evite bloquear otro recurso si ya lo mantiene one.It es casi imposible llegar a un punto muerto si está trabajando con un solo bloqueo de objeto.

  2. Bloquee solo lo que se requiera. Como bloquear un campo particular de objeto en lugar de bloquear todo el objeto si sirve a su propósito.

  3. No espere indefinidamente.

 1
Author: 027,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-14 03:29:07
  1. A menos que sea necesario, no comparta datos en varios subprocesos. Si los datos no se pueden cambiar después de la creación/inicialización, se adhieren a las variables finales.
  2. Si no puedes evitar los datos compartidos entre múltiples subprocesos, usa bloques granulares synchronized o Lock s.
  3. Si solo utiliza bloques de código synchronized, asegúrese de que los bloqueos se adquieren/liberan en un orden determinado.
  4. Busque otras alternativas: volátil o AtomicXXX variables o Lock API

Preguntas relacionadas:

Evitar sincronizado (esto) en Java?

Diferencia entre volátil y sincronizado en Java

Volatile boolean vs AtomicBoolean

 1
Author: Ravindra babu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:18:18
  • Evitar Bloqueos Anidados
  • Evitar Bloqueos innecesarios
  • Use thread join()
 1
Author: Arun Raaj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-24 23:14:22