2011-02-22 20 views

Respuesta

14

"Mejor" depende del contexto. Ellos son "igualmente poderosos" según James McParlane. Recomiendo ver his blog for a discussion on the differences.

aquí hay una guía rápida que encontré:

semáforos

  • Puede ser utilizado en cualquier parte de un programa, pero no debe ser utilizado en un monitor
  • Wait() no siempre bloquean el llamador (es decir, cuando el contador de semáforo es mayor que cero).
  • Signal() libera un hilo bloqueado, si hay uno, o aumenta el contador de semáforo.
  • Si Signal() libera un hilo bloqueado, el llamador y el hilo liberado continúan.

variables de condición

  • sólo se pueden utilizar en los monitores de
  • Wait() siempre bloquea la persona que llama.
  • Signal() libera un hilo bloqueado, si hay alguno, o la señal se pierde como si nunca sucediera.
  • Si Signal() libera un hilo bloqueado, el llamante cede el monitor (tipo Hoare) o continúa (Tipo de mesa). Solo uno de los llamantes o el hilo liberado puede continuar, pero no ambos.

Esta información de: http://www.cs.mtu.edu/~shene/NSF-3/e-Book/MONITOR/sema-vs-monitor.html

Algunos recursos útiles:

+3

Esto es interesante en general, pero no es directamente aplicable a Java, y por lo tanto es un poco confuso. Hoare y Mesa monitorean qué? – Air

+0

Sí, la pregunta fue hecha para Java, pero la respuesta no está relacionada con Java. – t0r0X

1

En primer lugar, que hav e para decidir qué JDK estás usando. Las primeras versiones de Java donde solo se proporcionan hilos. Desde Java Tiger (5.0), se han introducido nuevas clases para manejar la concurrencia. En particular, se ha proporcionado un paquete completo, el java.util.concurrent.

En mi experiencia, encontré que los monitores son mejores, ya que dejan el código más limpio. Por otra parte, su uso permite que el código más fácil de entender.Se llevan a cabo generalmente a través de una clase que implementa la bloqueo interfaz: las implementaciones más famosos proporcionados por el JDK son la clase ReentrantLock, que define un bloqueo general y la clase ReentrantReadWriteLock, que proporciona una específica escriben y/o lea cerradura.

Por lo tanto, un bloqueo se utiliza para habilitar/deshabilitar el acceso a un objeto compartido (por ejemplo, una lista de objetos).

A Semáforo objeto es un sincronizado utiliza para coordinar y controlar los hilos (hay muchas sincronizadores proporcionados en las últimas JDK, como Semáforo, CyclicBarrier, CountdownLatch, y Intercambiador clases). Por ejemplo, con un semáforo puede liberar un número fijo de tokens a su conjunto de subprocesos y así decidir la cantidad de operaciones que se pueden ejecutar simultáneamente. Personalmente, no me gusta este enfoque, ya que el uso de un conjunto de hilos con Futures y Locks conduce al mismo resultado de una manera más limpia y segura.

Más información se puede encontrar en este libro: "Java Concurrency in Practice" y en este tutorial de IBM: "Concurrency in JDK 5.0". Algunos ejemplos más agradables se pueden encontrar here.

3

Para confirmar, por monitores nos referimos a la buena palabra clave synchronized.

Primera pregunta, ¿necesita su cerradura para tener un contador?

  1. un semáforo puede tener un contador de mayor que uno. Si necesita proteger N recursos, el semáforo es el mejor. Decisión fácil
  2. Si está protegiendo un único recurso, este es el caso interesante en el que un semáforo (1) y un monitor son igualmente aplicables.

El J2SE 5.0 concurrency article da buenos consejos aquí. Los monitores son limitados debido a que:

  • No hay manera de dar marcha atrás de un intento de adquirir un bloqueo que ya se lleva a cabo, o que renunciar después de esperar durante un período de tiempo determinado, o para cancelar un intento de bloqueo después una interrupción
  • No hay forma de alterar la semántica de un bloqueo, por ejemplo, con respecto a la reentrada, la protección de lectura frente a escritura o la equidad.
  • La sincronización se realiza dentro de métodos y bloques, lo que limita el uso al bloqueo estructurado de bloques estricto. En otras palabras, no puede adquirir un bloqueo en un método y liberarlo en otro.

Por lo tanto, si alguno de estos elementos es importante para usted, dar marcha atrás después de un tiempo de espera es un gran ejemplo, entonces vaya con un semáforo. Si no, un monitor está bien.

7

Si usted está después de la reducción al mínimo dolor de cabeza, prefieren los monitores (synchronized bloques/métodos) más de semáforos donde se siente una verdadera elección de una primitiva de bloqueo. Ignora las conversaciones académicas sobre la flexibilidad de los semáforos. Usted busca fiabilidad, no capacidad de configuración, ¿verdad?

A menudo se afirma que los monitores y semáforos son equivalentes (pueden simularse entre sí), pero esta equivalencia es mucho más abstracta y menos útil que sometimes expected. Cualquiera que pueda correctamente simular uno con el otro ya no necesita ninguna respuesta a esta pregunta.

Obviamente, los semáforos son su única opción práctica en situaciones en las que el número de hilos a los que se les permite ingresar simultáneamente en un bloque es mayor que uno. Por lo tanto, el verdadero competidor de monitores es semáforos binarios, es decir, aquellos que se inicializan con un recuento de 1, y adicionalmente solo aquellos de los que espera el mismo hilo que realizó el bloqueo para desbloquear finalmente el semáforo. Entonces, miremos más de cerca exactamente esas situaciones.

La diferencia fundamental entre monitores y semáforos binarios es propiedad de hilo. Tiene una gran consecuencia, y esa es la capacidad de reentrancy. La reentrada significa que un hilo que ya posee un bloqueo puede adquirirlo nuevamente en lugar de bloquearlo. Esto es un gran problema si su clase ha compartido un estado que simplemente quiere proteger en todos los métodos, pero no puede permitirse suposiciones permanentes sobre cómo estos métodos se llaman entre sí; o con rasgos de cinturones y tirantes que evolucionan en su esquema de seguridad de hilos en general.

Los semáforos nunca vuelven a entrar y los monitores Java siempre son reentrantes. Si necesita bloquear el mismo objeto desde muchas ubicaciones de código, semaphores are prone to deadlocks, incluso en escenarios de subproceso único, y esta limitación de semáforos ofrece beneficios solo en escenarios relativamente raros donde los monitores no son realmente una opción.

La propiedad de subprocesos también reduce drásticamente el riesgo de olvidarse de bloquear, olvidarse de desbloquear, o actividades de un hilo que enmascaran las actividades de otro hilo. También hay una diferencia ergonómica significativa en la sintaxis de Java asociada.

Aviso también this question; aunque utiliza una terminología diferente, las mejores respuestas allí entienden que "mutex" significa un "monitor" de Java.

Cuestiones relacionadas