y dan acceso a abstracciones de simultaneidad completamente diferentes.
synchronized
es una forma de adquirir y liberar cerraduras. Cuando un hilo entra en un bloque synchronized
, intenta adquirir el bloqueo apropiado; si el bloqueo está retenido actualmente por un hilo diferente, el hilo actual bloquea y espera a que se libere. Esto conduce a ciertos problemas, como el riesgo de interbloqueo. El bloqueo se libera cuando el hilo sale del bloque synchronized
.
dosync
marca un bloque de código que se ejecutará en una transacción. Las transacciones en Clojure son una forma de coordinar los cambios en Refs (objetos creados con la función ref
); si necesita un código para tener una vista coherente de algunas piezas de estado mutable en Clojure, y posiblemente cambiarlas, las pone en Refs y ejecuta su código en una transacción.
Una transacción tiene la interesante propiedad de que se reiniciará si por alguna razón no puede confirmarse, hasta un cierto número máximo de intentos (actualmente codificados como 10000). Entre los posibles motivos por los que una transacción no puede comprometerse se encuentra la imposibilidad de obtener una visión coherente del mundo (en realidad, las referencias pertinentes - existe una función de "historia adaptativa" que hace que este problema no sea tan grande como podría parecer a la primera vista); cambios simultáneos realizados por otras transacciones; etc.
Una transacción no corre el riesgo de quedar estancada (a menos que el programador se desvíe de su camino para introducir un interbloqueo no relacionado con el sistema STM a través de la interoperabilidad Java); Livelock, por otro lado, es una cierta posibilidad, aunque no es muy probable. En general, muchos, ¡aunque no todos! - de las intuiciones que los programadores asociados con las transacciones de bases de datos son válidas en el contexto de los sistemas STM, incluido el de Clojure.
STM es un gran tema; Un recurso excelente para aprender sobre el STM de Clojure es el artículo de Mark Volkmann, Software Transactional Memory. Se profundiza en la discusión del STM de Clojure en sus secciones finales, pero el comienzo puede ser una gran lectura introductoria.
En cuanto al fragmento que citó, en realidad no es algo que normalmente desee emular en el código de producción, ya que los bloques dosync
casi siempre deberían tener efectos secundarios libres; El print
aquí puede ser útil para demostrar el funcionamiento interno del STM, pero si desea que una transacción cause efectos colaterales en el código real, debe hacer que genere un agente Clojure para ese fin (que solo ejecutaría su tarea si el la transacción se compromete con éxito).
De nada. :-) –
Hola, Michl, como me respondiste perfectamente sobre STM, déjame preguntarte otras cosas sobre clojure de las que no me doy cuenta. La forma de Conmutar. Supongamos que tengo 2 hilos (t1 y t2). Y la ideia es incrementar una referencia, ¿de acuerdo? t1 dentro de una dosincronización, obtenga el valor de referencia - en el valor de transacción (0) - ... t2 obtenga el control y pueda incrementar la referencia de 0 a 1. t1 vuelva, y ¿qué se supone que debe hacer? Si t1 continúa ejecutando el resultado final, no será correcto. ¿Cómo funciona el viaje al trabajo en este caso? gracias de antemano – CHAPa