thread method lock intrinsic example java multithreading concurrency locking

intrinsic - lock method java



Enhebrado en Java: cómo bloquear un objeto? (7)

¿Quizás el método que estás buscando es Thread.sleep(long) ? Este método esperará (como detener la ejecución del subproceso) durante el tiempo especificado en milisegundos antes de reanudar.

object.wait(long) (que es lo que estás usando) hace algo completamente diferente. Espera a que otro objeto de otro hilo lo notifique (es decir, le envíe una especie de mensaje de activación) y esperará como máximo el número especificado de milisegundos. Dado el código que publicaste, dudo mucho que esto sea lo que realmente quieres.

Si Thread.sleep () no es lo que quieres, entonces debes usar el bloque sincronizado como lo mencionaron los otros carteles.

La siguiente función se está ejecutando en su propio hilo:

private void doSendData() { try { //writeToFile(); // just a temporary location of a call InetAddress serverAddr = InetAddress.getByName(serverAddress); serverAddr.wait(60000); //Log.d("TCP", "C: Connecting..."); Socket socket = new Socket(serverAddr, portNumber); socket.setSoTimeout(3000); try { //Log.d("TCP", "C: Sending: ''" + message + "''"); PrintWriter out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())),true); String message = packData(); out.println(message); Log.d("TCP", "C: Sent."); Log.d("TCP", "C: Done."); connectionAvailable = true; } catch(Exception e) { Log.e("TCP", "S: Error", e); connectionAvailable = false; } finally { socket.close(); announceNetworkAvailability(connectionAvailable); } } catch (Exception e) { Log.e("TCP", "C: Error", e); announceNetworkAvailability(connectionAvailable); } }

Cuando la ejecución llega a la línea serverAddr.wait(60000) arroja una excepción:

java.lang.IllegalMonitorStateException: object not locked by thread before wait()

¿Alguien sabe cómo bloquear un objeto o una función para evitar la concurrencia? Intenté agregar un objeto de bloqueo:

private final Lock lock = new ReentrantLock();

y la linea

boolean locked = lock.tryLock();

al comienzo de la función pero no funcionó.


El siguiente código debería funcionar.

private final ReentrantLock lock = new ReentrantLock(); lock.lock(); // block until condition holds try { serverAddr.wait(60000); } finally { lock.unlock() } }

Consulte esta page documentación para más detalles.

public void lock()

Adquiere el candado

Adquiere el bloqueo si no está retenido por otro hilo y lo devuelve inmediatamente, estableciendo el conteo de bloqueo de bloqueo en uno.

Si el hilo actual ya contiene el bloqueo, el conteo de espera se incrementa en uno y el método regresa inmediatamente.

Si el bloqueo está retenido por otro hilo, el hilo actual se desactiva para fines de programación del hilo y permanece inactivo hasta que se haya adquirido el bloqueo, en cuyo momento el contador de bloqueo se establece en uno

Consulte esta pregunta SE para conocer las ventajas de la synchronization de lock sobre:

Sincronización vs bloqueo


En general, cuando tienes un programa de subprocesos múltiples en Java, necesitas bloquear la variable compartida usando synchronized (palabra clave) y luego, en cualquier momento, solo un subproceso puede acceder a la memoria compartida.


Lo anterior es correcto Puede usar un bloque de código sincronizado. O puede crear lo que ellos llaman un mutex. Un mutex puede ser cualquier objeto. Muchas personas simplemente usan Object como un mutex. Entonces puedes bloquear el mutex. Cualquier subproceso que desee obtener acceso debe esperar al hilo que contiene el mutex para liberarlo.

Hubo también una sugerencia de Apocalisp. También recomendaría que miraras el paquete java.util.concurrent.


Para evitar ese mensaje de error, use la palabra clave sincronizada:

synchronized(serverAddr){ serverAddr.wait(60000); }


Para llamar a wait () en un objeto, debe mantener el bloqueo sincronizado en ese objeto (aunque el bloqueo se libera realmente mientras el hilo está esperando):

synchronized (serverAddr) { serverAddr.wait(); }

Tengo que admitir que el por qué quieres hacer esto me desconcierta en este caso ...


Siempre me estremezco cuando veo este tipo de código. Hazte un favor y eche un vistazo al paquete java.util.concurrent .