2009-11-26 13 views
8

tenemos dos hilos que acceden a una lista a través de un método sincronizado. ¿PodemosAsegúrese de que los bloqueos sincronizados de Java se toman en orden?

a) confiar en el tiempo de ejecución para asegurarse de que cada uno de ellos recibirá el acceso al método basado en el orden en que intentaron o

b) ¿el VM Siga todas las demás reglas

c) ¿Hay alguna forma mejor de serializar las solicitudes?

¡Muchas gracias!

+1

Es bastante improbable que realmente necesite este requisito. Puede encontrar que usar ReentrantLock (verdadero) es sustancialmente más lento que realizar toda la operación con sincronización. –

Respuesta

17

No, sincronizado dará acceso en cualquier orden (Depende de la implementación de JVM). Esto podría incluso provocar que Threads muera de hambre en algunos escenarios.

Puede garantizar el orden utilizando ReentrantLock (desde Java 5.0) con la opción fair=true. (Lock lock = new ReentrantLock(true);)

+4

"sincronizado dará acceso en orden aleatorio (o quién es el más rápido para agarrar el bloqueo)". La orden simplemente no se especifica. Ciertamente, NO es aleatorio, y depende de la implementación (y es altamente improbable) que el "primer" hilo siempre obtenga el bloqueo ... especialmente en un sistema multiprocesador. –

+2

Tienes razón, Stephen. Pero no se puede retransmitir en una implementación específica, por lo que el programador debe esperar un comportamiento aleatorio. – Hardcoded

+1

El orden no es aleatorio ni se garantiza que sea aleatorio. Tan pronto como un hilo se bloquea, puede cambiarse de contexto para que no vuelva a intentarlo durante un tiempo, por lo que puede obtener un hilo entre muchos obteniendo el bloqueo muchas veces antes de que otro hilo tenga la oportunidad de despertarse. –

-1

Sí.

Si el acceso a la lista se realiza a través de un método sincronizado, las solicitudes simultáneas de varios subprocesos se serializarán.

+2

@Conrad. No creo que sea verdad Cuando múltiples subprocesos están esperando un monitor, cualquiera de ellos se puede otorgar dependiendo de la implementación. No podemos estar seguros de que el monitor se otorgará en el orden en que los hilos lo solicitaron. – Varun

+4

Está respondiendo una pregunta sutilmente diferente de lo que se le preguntó. MrG pregunta sobre el orden de programación de los bloques sincronizados controvertidos, no si se obedecen los bloques sincronizados. –

+0

Sí, aunque creo que no importa la mayor parte del tiempo. –

10

No, no puede estar seguro de que se producirán dos llamadas a un método sincronizado en orden. El orden no está especificado y depende de la implementación.

Esto se define en la sección 17.1 Locks del JLS. Tenga en cuenta que no dice nada sobre el orden en que los hilos que esperan en un candado deberían tener acceso.

+0

Como su respuesta, aunque no decir nada no necesariamente implica que no habrá un pedido, así que supongo que dependerá de la implementación. Y supongo que HotSpot/OpenJDK dependen del programador de hilos del sistema operativo. – user454322

+0

@ user454322 - esa es una evaluación justa. –

3

No puede confiar en el orden en que se llama el método particular desde cada subproceso. Si solo son dos hilos, puede ser que sí. Pero imagine si hay 3 hilos y 1 hilo ya adquirido. Los otros 2 subprocesos cuando intenten acceder esperarán y se les puede otorgar acceso a cualquiera de ellos, y esto no depende del orden en el que llamaron a este método. Por lo tanto, no se recomienda confiar en la orden.

+3

"Por lo tanto, no se recomienda confiar en la orden". - ¡¡Eso es un eufemismo!! Yo diría que cualquier programa que confíe en él es * definitivamente * no portátil, y * probablemente * defectuoso en la plataforma en la que fue implementado/probado. –

+0

@Stephen No puedo estar más de acuerdo. – Varun

0

c) ¿Existe alguna forma mejor de serializar las solicitudes?

¿Está usted por casualidad usando la lista como cola, es decir, el patrón de uso se parece a esto?

 
while (some condition) { 
    synchronized(theList){ 
     anItem = get and remove an element from theList 
    } 
    do some work with anItem 
} 

Si es así, es posible que desee ver en la interfaz en lugar de utilizar sus propias combinaciones de bloqueo BlockingQueue. Las implementaciones (como ArrayBlockingQueue) tienen configuraciones para la equidad y más.

0

Siempre dejo la sincronización al servidor de aplicaciones o al motor a menos que defina la propia intensidad

Cuestiones relacionadas