variable todos tiempo son quiere que objetos objetivo métodos metodo los hereda esperar ejemplo decir cual clase arreglos java multithreading wait notify

java - tiempo - Concepto detrás de poner los métodos wait(), notify() en la clase Object



variable object java (11)

Esta pregunta ya tiene una respuesta aquí:

Solo estoy teniendo dificultades para entender el concepto detrás de poner wait() en la clase Object . Para este asunto, considere si wait() y notifyAll() están en la clase Thread .

class Reader extends Thread { Calculator c; public Reader(Calculator calc) { c = calc; } public void run() { synchronized(c) { //line 9 try { System.out.println("Waiting for calculation..."); c.wait(); } catch (InterruptedException e) {} System.out.println("Total is: " + c.total); } } public static void main(String [] args) { Calculator calculator = new Calculator(); new Reader(calculator).start(); new Reader(calculator).start(); new Reader(calculator).start(); calculator.start(); } } class Calculator extends Thread { int total; public void run() { synchronized(this) { //Line 31 for(int i=0;i<100;i++) { total += i; } notifyAll(); } } }

Mi pregunta es ¿qué diferencia podría haber hecho? En la línea 9 estamos adquiriendo el bloqueo en el objeto c y luego ejecutando wait que satisface la condición de espera que necesitamos adquirir lock en el objeto antes de usar wait y así es el caso de notify. Todos hemos adquirido lock en el objeto de Calculator en la línea 31 .


Solo estoy teniendo dificultades para entender el concepto detrás de poner wait () en la clase de objeto. Por este motivo, considere como si wait () y notifyAll () estuvieran en la clase de subprocesos

En el lenguaje Java, wait() en una instancia particular de un Object , un monitor asignado a ese objeto para ser preciso. Si desea enviar una señal a un hilo que está esperando en esa instancia de objeto específico, llame a notify() en ese objeto. Si desea enviar una señal a todos los hilos que están esperando en esa instancia de objeto, use notifyAll() en ese objeto.

Si wait() y notify() estaban en el Thread entonces cada subproceso debería conocer el estado de cada otro subproceso. ¿Cómo sabría thread1 que ese thread2 estaba esperando el acceso a un recurso en particular? Si thread1 necesitaba llamar a thread2.notify() , de alguna manera tendría que descubrir que thread2 estaba esperando. Tendría que haber algún mecanismo para que los subprocesos registraran los recursos o acciones que necesitan para que otros puedan señalarlos cuando las cosas estuvieran listas o disponibles.

En Java, el objeto en sí es la entidad que se comparte entre hilos, lo que les permite comunicarse entre ellos. Los hilos no tienen conocimiento específico entre ellos y pueden ejecutarse de forma asíncrona. Se ejecutan y bloquean, esperan y notifican sobre el objeto al que quieren acceder. No tienen conocimiento de otros hilos y no necesitan saber su estado. No necesitan saber que es thread2 el que está esperando el recurso; solo notifican sobre el recurso y se notificará a quien esté esperando (si hay alguien).

En Java, utilizamos objetos de bloqueo como sincronización, mutex y puntos de comunicación entre hilos. Nos sincronizamos en un objeto de bloqueo para obtener acceso mutex a un bloque de código importante y para sincronizar la memoria. Esperamos un objeto si esperamos que cambie alguna condición: algún recurso estará disponible. Notificamos sobre un objeto si queremos despertar hilos para dormir.

// locks should be final objects so the object instance we are synchronizing on, // never changes private final Object lock = new Object(); ... // ensure that the thread has a mutex lock on some key code synchronized (lock) { ... // i need to wait for other threads to finish with some resource // this releases the lock and waits on the associated monitor lock.wait(); ... // i need to signal another thread that some state has changed and they can // awake and continue to run lock.notify(); }

Puede haber cualquier número de objetos de bloqueo en su programa, cada uno bloqueando un recurso o segmento de código en particular. Puede tener 100 objetos de bloqueo y solo 4 hilos. A medida que los hilos ejecutan las distintas partes del programa, obtienen acceso exclusivo a uno de los objetos de bloqueo. Una vez más, no tienen que saber el estado de ejecución de los otros hilos.

Esto le permite ampliar o reducir el número de subprocesos que se ejecutan en su software tanto como lo desee. Encuentra que los 4 hilos bloquean demasiado recursos externos, luego puede aumentar el número. Si presiona demasiado el servidor maltratado, reduzca la cantidad de subprocesos en ejecución. Los objetos de bloqueo aseguran la exclusión mutua y la comunicación entre los subprocesos independientemente de cuántos subprocesos se están ejecutando.


El método wait() liberará el bloqueo en el objeto especificado y esperará cuando recupere el bloqueo.

el notifyAll() notify() , notifyAll() verificará si hay hilos esperando para obtener el bloqueo de un objeto y si es posible se lo dará.

La razón por la cual los bloqueos son parte de los objetos es porque los recursos (RAM) están definidos por Object y no por Thread .

El método más fácil de entender es que los hilos pueden compartir objetos (en el ejemplo es una calculadora compartida por todos los hilos), pero los objetos no pueden compartir atributos (como primitivas, incluso las referencias a los objetos no se comparten, simplemente apuntan a la misma ubicación ) Por lo tanto, para garantizar que solo un hilo modifique un objeto, se utiliza el sistema de bloqueo sincronizado


El método de esperar y notificar siempre invoca al objeto, por lo tanto, si puede ser un objeto de subproceso o un objeto simple (que no amplía la clase de subproceso), el ejemplo dado borrará todas sus dudas.

He llamado a esperar y notificar en la clase ObjB y esa es la clase Thread, por lo que podemos decir que se llama a wait y notify en cualquier objeto.

public class ThreadA { public static void main(String[] args){ ObjB b = new ObjB(); Threadc c = new Threadc(b); ThreadD d = new ThreadD(b); d.setPriority(5); c.setPriority(1); d.start(); c.start(); } } class ObjB { int total; int count(){ for(int i=0; i<100 ; i++){ total += i; } return total; }} class Threadc extends Thread{ ObjB b; Threadc(ObjB objB){ b= objB; } int total; @Override public void run(){ System.out.print("Thread C run method"); synchronized(b){ total = b.count(); System.out.print("Thread C notified called "); b.notify(); } } } class ThreadD extends Thread{ ObjB b; ThreadD(ObjB objB){ b= objB; } int total; @Override public void run(){ System.out.print("Thread D run method"); synchronized(b){ System.out.println("Waiting for b to complete..."); try { b.wait(); System.out.print("Thread C B value is" + b.total); } catch (InterruptedException e) { e.printStackTrace(); } } } }


En términos simples, las razones son las siguientes.

  1. Object tiene monitores.
  2. Múltiples hilos pueden acceder a un Object . Solo un hilo puede contener el monitor de objetos a la vez para synchronized métodos / bloques synchronized .
  3. wait(), notify() and notifyAll() método wait(), notify() and notifyAll() que está en la clase Object permite que todos los hilos creados en ese object comuniquen con otros
  4. Bloquear (usando synchronized or Lock API) y Comunicación ( wait() and notify() ) son dos conceptos diferentes.

Si la clase Thread contiene los métodos wait(), notify() and notifyAll() , creará los siguientes problemas:

  1. Problema de comunicación con el Thread
  2. Synchronization en el objeto no será posible. Si cada hilo tendrá monitor, no tendremos ningún modo de lograr la sincronización
  3. Inconsistency en el estado del objeto

Consulte este article para más detalles.


Esto es solo mis 2 centavos en esta pregunta ... no estoy seguro de si esto es cierto en su totalidad.

Cada objeto tiene un monitor y conjunto de espera -> conjunto de hilos (esto es probablemente más en el nivel del sistema operativo). Esto significa que el monitor y el waitset se pueden ver como miembros privados de un objeto. Tener los métodos wait () y notify () en la clase Thread significaría dar acceso público al waitset o usar los métodos get-set para modificar el waitset. No querrías hacer eso porque es un mal diseño.

Ahora que el Objeto sabe el / los hilo / s que espera su monitor, el Objeto debe ir y despertar los hilos que lo esperan en lugar de un Objeto de la clase de hilo y despertar cada uno de ellos (que sería posible solo si el objeto de clase de subproceso tiene acceso al conjunto de espera). Sin embargo, no es tarea de un hilo en particular ir y despertar cada uno de los hilos de espera. (Esto es exactamente lo que sucedería si todos estos métodos estuvieran dentro de la clase Thread). Su trabajo es simplemente liberar el bloqueo y avanzar con su propia tarea. Un subproceso funciona de manera independiente y no necesita saber si otros subprocesos están esperando el monitor de objetos (es un detalle innecesario para el objeto de clase de subproceso). Si comenzó a despertar cada hilo por sí mismo ... se está alejando de su funcionalidad principal y eso es para llevar a cabo su propia tarea. Cuando piensas en una escena en la que puede haber miles de hilos ... puedes asumir cuánto impacto en el rendimiento puede crear. Por lo tanto, dado que Object Class sabe quién lo está esperando, puede llevar a cabo el trabajo despertando los hilos de espera y el hilo que envió notify () puede llevar a cabo con su procesamiento posterior.

Para dar una analogía (tal vez no la correcta, pero no puedo pensar en otra cosa). Cuando tenemos un corte de energía, llamamos a un representante de atención al cliente de esa compañía porque ella conoce a las personas adecuadas para ponerse en contacto para solucionarlo. Usted, como consumidor, no puede saber quiénes son los ingenieros que lo respaldan e, incluso si lo sabe, no puede llamar a cada uno de ellos y hablarles de sus problemas (esa no es su obligación. Su deber es informarles sobre la interrupción y el trabajo de la RC es ir y notificar (despertar) a los ingenieros adecuados para ello).

Avísame si esto suena bien ... (A veces tengo la habilidad de confundir con mis palabras).


Estos métodos funcionan en los bloqueos y los bloqueos están asociados con objetos y no hilos. Por lo tanto, está en la clase Object.

Los métodos wait (), notify () y notifyAll () no son solo métodos, sino que son una herramienta de sincronización que se utiliza en el mecanismo de comunicación entre subprocesos en Java.

Para una explicación más detallada, por favor visite: http://parameshk.blogspot.in/2013/11/why-wait-notify-and-notifyall-methods.html


La respuesta a su primera pregunta es Como cada objeto en Java tiene solo un lock(monitor) y wait(),notify(),notifyAll() se utilizan para compartir monitores por eso son parte de la clase Object lugar de la clase Thread .


Las otras respuestas a esta pregunta omiten el punto clave que en Java, hay un mutex asociado con cada objeto. (Supongo que sabes qué es un mutex o "bloqueo"). Este no es el caso en la mayoría de los lenguajes de programación que tienen el concepto de "bloqueos". Por ejemplo, en Ruby, tienes que crear explícitamente tantos objetos Mutex como necesites.

Creo que sé por qué los creadores de Java hicieron esta elección (aunque, en mi opinión, fue un error). El motivo tiene que ver con la inclusión de la palabra clave synchronized . Creo que los creadores de Java (ingenuamente) pensaron que al incluir métodos synchronized en el lenguaje, sería fácil para las personas escribir el código correcto multiproceso: simplemente encapsular todo su estado compartido en objetos, declarar los métodos que acceden a ese estado como synchronized , ¡y listo! Pero no funcionó de esa manera ...

De todos modos, dado que cualquier clase puede tener métodos synchronized , es necesario que haya un mutex para cada objeto, que los métodos synchronized pueden bloquear y desbloquear.

wait y notify ambos dependen de mutexes. Tal vez ya entiendas por qué este es el caso ... si no, puedo agregar más explicaciones, pero por ahora, digamos que ambos métodos deben funcionar en un mutex. Cada objeto Java tiene un mutex, por lo que tiene sentido que se pueda llamar a wait y notify en cualquier objeto Java. Lo que significa que deben declararse como métodos de Object .

Otra opción habría sido poner métodos estáticos en Thread o algo así, lo que tomaría cualquier Object como argumento. Eso habría sido mucho menos confuso para los nuevos programadores de Java. Pero no lo hicieron de esa manera. Es demasiado tarde para cambiar cualquiera de estas decisiones; ¡demasiado!


Para comprender mejor por qué los métodos wait () y notify () pertenecen a la clase Object, le daré un ejemplo de la vida real: supongamos que una estación de servicio tiene un solo inodoro, cuya clave se guarda en la mesa de servicio. El baño es un recurso compartido para los automovilistas que pasan. Para usar este recurso compartido, el usuario potencial debe adquirir una clave para el candado en el inodoro. El usuario va a la mesa de servicio y adquiere la llave, abre la puerta, la bloquea desde el interior y usa las instalaciones.

Mientras tanto, si un segundo usuario potencial llega a la estación de servicio, encuentra que el inodoro está bloqueado y, por lo tanto, no está disponible para él. Va al servicio de atención al cliente, pero la clave no está allí porque está en manos del usuario actual. Cuando el usuario actual finaliza, él desbloquea la puerta y devuelve la llave a la mesa de servicio. Él no se molesta en esperar a los clientes. El mostrador de servicio le da la clave al cliente que está esperando. Si aparece más de un posible usuario mientras el baño está cerrado, debe formar una cola esperando la llave del candado. Cada hilo no tiene idea de quién está en el baño.

Obviamente, al aplicar esta analogía a Java, un hilo de Java es un usuario y el inodoro es un bloque de código que el hilo desea ejecutar. Java proporciona una forma de bloquear el código para un hilo que se está ejecutando actualmente usando la palabra clave sincronizada, y hacer que otros hilos que deseen usarlo esperen hasta que termine el primer hilo. Estos otros hilos se colocan en el estado de espera. Java NO ES TAN FÁCIL como la estación de servicio porque no hay cola para hilos en espera. Cualquiera de los hilos de espera puede obtener el monitor siguiente, independientemente del orden que lo pidieron. La única garantía es que todos los hilos llegarán a utilizar el código supervisado tarde o temprano.

Finalmente, la respuesta a su pregunta: el bloqueo podría ser el objeto clave o el servicio técnico. Ninguno de los cuales es un hilo.

Sin embargo, estos son los objetos que actualmente deciden si el inodoro está cerrado o abierto. Estos son los objetos que están en condiciones de notificar que el baño está abierto ("notificar") o pedir a las personas que esperen cuando esté bloqueado, espere.


las operaciones de espera y notificación funcionan en el bloqueo implícito, y el bloqueo implícito es algo que hace posible la comunicación entre subprocesos. Y todos los objetos tienen su propia copia de objeto implícito. así que mantener la espera y notificar dónde vive el bloqueo implícito es una buena decisión.

Alternativamente, esperar y notificar podría haber vivido en la clase Thread también. que en lugar de wait () podemos tener que llamar a Thread.getCurrentThread (). wait (), lo mismo con notify. Para las operaciones de espera y notificación, hay dos parámetros obligatorios, uno es el hilo que estará esperando o el otro que lo está notificando es el bloqueo implícito del objeto. ambos pueden estar disponibles tanto en Object como en thread class. El método wait () en la clase Thread habría hecho lo mismo que está haciendo en la clase Object, la transición del hilo actual al estado de espera espera en el bloqueo que había adquirido por última vez.

Así que sí, creo que wait and notify podría haber estado allí también en la clase Thread, pero es más como una decisión de diseño para mantenerlo en la clase de objetos.


wait - wait method le dice al hilo actual que abandone el monitor y se vaya a dormir.

notificar - Despierta un hilo único que está esperando en el monitor de este objeto.

Entonces ve que los métodos wait () y notify () funcionan en el nivel del monitor, se le pide a la secuencia que está actualmente sujetando el monitor que abandone ese monitor a través del método wait () y a través de los hilos de método de notificación (o notifyAll) que están esperando en el el monitor del objeto recibe una notificación de que los subprocesos pueden activarse.

Un punto importante a tener en cuenta aquí es que el monitor se asigna a un objeto, no a un hilo en particular. Esa es una razón por la cual estos métodos están en la clase Object. Para reiterar que los hilos esperan en el monitor de un objeto (bloqueo) y notificar () también se llama a un objeto para activar un hilo esperando en el monitor del objeto.