java multithreading deadlock

Consejos para evitar interbloqueos en java



multithreading deadlock (10)

Estoy estudiando los hilos de java y los interbloqueos, entiendo los ejemplos de interbloqueo, 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 interbloqueos. En caso afirmativo, ¿podría explicar cómo implementarlo?


  1. Evite los bloqueos mediante el uso de estructuras de datos libres de bloqueo (por ejemplo, utilice una ConcurrentLinkedQueue lugar de una ArrayList sincronizada)
  2. Adquiera siempre las cerraduras en el mismo orden, por ejemplo, asigne un valor numérico exclusivo a cada cerradura y adquiera las cerraduras con un valor numérico más bajo antes de adquirir las cerraduras con un valor numérico superior.
  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)

  1. No use cerraduras.
  2. Si debe, mantenga sus bloqueos locales. Los bloqueos globales pueden ser realmente complicados.
  3. Haz lo menos posible cuando sostienes el candado.
  4. Use rayas para solo bloquear segmentos de sus datos
  5. Prefiere tipos inmutables. Muchas veces esto significa copiar datos en lugar de compartir datos.
  6. Use mecánicas de comparación y configuración (CAS) en su lugar, consulte AtomicReference por ejemplo.

Algunos consejos rápidos de mi cabeza

  • no use múltiples hilos (como Swing lo hace, por ejemplo, ordenando que todo se haga en el EDT)
  • no sostenga varios bloqueos a la vez. Si lo hace, siempre adquiera las cerraduras en el mismo orden
  • no ejecute código extraño mientras mantiene un bloqueo
  • usar bloqueos interrumpibles

Este es un ejemplo clásico de punto muerto:

public void methodA(){ synchronized(lockA){ //... synchronized(lockB){ //... } } } public void methodB(){ synchronized(lockB){ //... synchronized(lockA){ //... } } }

Este método probablemente crearía un gran interbloqueo si es invocado 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 interbloqueos, por lo que si desea evitarlos, asegúrese de que los bloqueos se adquieran en orden .


Existe una gran regla cuando se trata de prevenir bloqueos:

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

Sin embargo, mantener tu código libre de bloqueos debería ser siempre tu objetivo. Puede tratar de deshacerse de ellos mediante el uso de objetos locales inmutables o de subprocesos y estructuras de datos sin bloqueos.


Dada una opción de diseño, utilice 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 :)


Encapsular, encapsular, encapsular! Probablemente el error más peligroso que pueda cometer con los candados es exponer su bloqueo al mundo (hacerlo público). No hay forma de saber qué puede pasar si haces esto, ya que cualquiera podría adquirir el bloqueo sin que el objeto lo sepa (esta es la razón por la cual no debes bloquearlo). Si mantiene su bloqueo en privado, tendrá control total y esto lo hace más manejable.


Lee y entiende Java: Concurrencia y práctica. No se trata de "consejos" para evitar un punto muerto. Nunca contrataría a un desarrollador que conociera algunos consejos para evitar un punto muerto y, a menudo, evitar un punto muerto. Se trata de entender la concurrencia. Afortunadamente, hay un libro completo de nivel intermedio sobre el tema, así que ve a leerlo.


  1. Evite los bloqueos anidados. Esta es la razón más común para un punto muerto. Evite bloquear otro recurso si ya tiene uno. Es casi imposible quedarse estancado si está trabajando con un solo bloqueo de objeto.

  2. Bloquee solo lo que se requiere. Como bloquear un campo particular de objeto en lugar de bloquear todo el objeto si cumple con su propósito.

  3. No esperes indefinidamente.


  1. A menos que sea necesario, no comparta datos a través de múltiples hilos. Si los datos no se pueden cambiar después de la creación / inicialización, adhiérase a las variables finales.
  2. Si no puede evitar compartir datos entre múltiples hilos, use bloques granulares synchronized o Lock s.
  3. Si está utilizando solo bloques de código synchronized , asegúrese de que los bloqueos se adquieran / liberen en un orden determinado.
  4. Tenga cuidado con otras alternativas: variables volátiles o AtomicXXX o Lock API

Preguntas relacionadas con SE:

Evitar sincronizado (esto) en Java?

Diferencia entre volátil y sincronizado en Java

Volatile boolean vs AtomicBoolean