2011-12-02 16 views
8

¿Alguien puede darme un buen pequeño ejemplo? Demostrar la funcionalidad wait() y notify() en java. Lo he intentado con el siguiente código pero no muestra lo que esperaba.Un buen pequeño ejemplo para demostrar el método wait() y notify() en java

public class WaitDemo { 
    int i = 10; 

    int display() { 
     System.out.println("Lexmark"); 
     i++; 
     return i; 
    } 
} 
public class ClassDemo1 extends Thread { 

    private WaitDemo wd = new WaitDemo(); 

    public static void main(String[] args) { 
     ClassDemo1 cd1 = new ClassDemo1(); 
     ClassDemo1 cd2 = new ClassDemo1(); 
     cd1.setName("Europe"); 
     cd2.setName("America"); 
     cd1.start(); 
     cd2.start(); 

    } 

    synchronized void display() { 
     System.out.println("Hello"); 
     notifyAll(); 
    } 

    public void run() { 

     synchronized (this) { 
      try { 
       { 
        notify(); 
        System.out.println("The thread is " + currentThread().getName()); 
        wait(); 
        System.out.println("The value is " + wd.display()); 
       } 
      } catch (InterruptedException e) { 

      } 

     } 
    } 
} 

La cuestión es que el método en la clase WaitDemo no está siendo ejecutado y según mi idea del SOP después de esperar() debe ejecutar. Por favor, ayúdame en esto.

+6

¿No es eso para lo que es Google? – mre

+7

@ Крысa: Recuerde que uno de los objetivos de SO es ser el principal éxito en las búsquedas de Google (y otras). Esta es una pregunta perfectamente razonable. Debe ser respondido con un ejemplo - aquí, en SO, no en otro lado - y discusión (idealmente) de dónde Sourav salió mal arriba. –

+2

¿Cuál es el comportamiento esperado de este programa? – GETah

Respuesta

3

Tiene dos niveles de llaves { en su bloque try. Si quita el conjunto interno (que no parece hacer nada), ¿soluciona el problema?

Existen varios ejemplos, todos los cuales demuestran el uso. El último enlace es un conjunto de resultados que pueden ayudarte. Si necesita cosas más específicas, dígame qué intenta hacer su aplicación y puedo intentar encontrar ejemplos más específicos para su situación.

0

Su problema es que va a crear dos instancias de la clase Thread. Por lo tanto, cuando se invoca wait(), está en dos instancias diferentes, ninguna de las cuales tiene otro subproceso que esté en disputa para su monitor, ni hay otro subproceso que llame a notifyAll() para activar el subproceso desde su estado de espera.

Por lo tanto, cada hilo que haya iniciado esperará por siempre (o hasta que se interrumpa por algún otro motivo).

Desea que varios subprocesos accedan al mismo monitor, así que empiece por intentar codificar algo en el que el código en cuestión no es en realidad un subproceso, sino que simplemente está siendo utilizado por un subproceso.

@normalocity ya ha proporcionado enlaces a múltiples ejemplos.

0

Acabo de actualizar this answer para incluir un SCCE.

Los trabajadores llaman a pauseIfNeeded en el WorkerPauseManager. Si el administrador está en pausa cuando el hilo de trabajo llama a pauseIfNeeded(), llamamos a wait(), que le dice al hilo de llamada que espere hasta que un hilo diferente llame a notify() o notifyAll() al objeto que se espera. Esto sucede cuando el subproceso de envío de evento Swing llama a play() en el administrador, que a su vez llama a notifyAll().

Tenga en cuenta que debe tener un bloqueo sincronizado en el objeto al que está llamando wait() o notify() activado. Como los métodos en WorkerPauseManager están sincronizados, todos los métodos sincronizados obtienen un bloqueo sincronizado en el WorkerPauseManager.

import javax.swing.*; 
import java.awt.event.ActionEvent; 

/** 
* @author sbarnum 
*/ 
public class WorkerPauseManagerTest { 
    public static void main(String[] args) { 
     final WorkerPauseManager pauseManager = new WorkerPauseManager(); 
     new Worker("Worker 1", pauseManager).start(); 
     new Worker("Worker 2", pauseManager).start(); 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       JToggleButton playPauseButton = new JToggleButton(new AbstractAction("Pause") { 
        public void actionPerformed(final ActionEvent e) { 
         JToggleButton source = (JToggleButton) e.getSource(); 
         if (source.isSelected()) { 
          pauseManager.start(); 
          source.setText("Pause"); 
         } else { 
          pauseManager.pause(); 
          source.setText("Play"); 
         } 
        } 
       }); 
       playPauseButton.setSelected(true); // already running 
       JOptionPane.showMessageDialog(null, playPauseButton, "WorkerPauseManager Demo", JOptionPane.PLAIN_MESSAGE); 
       System.exit(0); 
      } 
     }); 

    } 

    private static class Worker extends Thread { 
     final String name; 
     final WorkerPauseManager pauseManager; 

     public Worker(final String name, final WorkerPauseManager pauseManager) { 
      this.name = name; 
      this.pauseManager = pauseManager; 
     } 

     @Override 
     public void run() { 
      while (!Thread.interrupted()) { 
       try { 
        pauseManager.pauseIfNeeded(); 
        System.out.println(name + " is running"); 
        Thread.sleep(1000L); 
       } catch (InterruptedException e) { 
        throw new RuntimeException(e); 
       } 
      } 
     } 
    } 

    public static final class WorkerPauseManager { 

     private boolean paused; 

     public synchronized void pauseIfNeeded() throws InterruptedException { 
      if (paused) wait(); 
     } 

     public synchronized void pause() { 
      this.paused = true; 
     } 

     public synchronized void start() { 
      this.paused = false; 
      notifyAll(); 
     } 
    } 
} 
-2
/* 
* the below program is like 
* tread t1 will first run , and it comes to "notify()" method 
* there are no threds waiting bcoz this is the first thread. 
* so it will not invoke any other threads. next step is "wait()" method 
*will be called and the thread t1 in waiting state. next stament 
* "System.out.println("The value is ..."+wd.display());" will not be executed 
* because thread t1 is in waiting state. 
* 
* thread t2 will run ,and it comes to "notify()" method ,there is already 
* thread t1 is in waiting state ,then it will be invoked.now thread t1 will 
* continue execution and it prints the statement "System.out.println("The value is ..."+wd.display())" 
* and thread t2 will be in waiting state now. 
* 
* if you uncomment "notifyAll()" method then, after t1 thread completes its execution 
*then immediately "notifyAll()" method will be called,by that time thread t2 is 
* already in waiting state , then thread t2 will be invoked and continues execution. 
*or 
* if any other threadds are in waiting state all those threads will be invoked. 
*/ 
package threadsex; 

/** 
* 
* @author MaheshM 
*/ 
/** 
* @param args the command line arguments 
*/ 
public class WaitNotifyNotifyAllDemo implements Runnable { 
    WaitDemo wd = new WaitDemo(); 

    public static void main(String[] args) { 
     WaitNotifyNotifyAllDemo cd1 = new WaitNotifyNotifyAllDemo(); 
     Thread t1 = new Thread(cd1); 
     t1.setName("mahi1"); 
     Thread t2 = new Thread(cd1); 
     t2.setName("mahi2"); 
     t1.start();   
     t2.start(); 
    } 

    @Override 
    public void run() { 
     synchronized (this) { 
      try { 

       System.out.println("The thread is=" + 
         Thread.currentThread().getName()); 
       notify(); 
       wait(); 
       System.out.println("The value is ..." + wd.display()); 
       //   notifyAll(); 

      } catch (Exception ex) { 
       ex.printStackTrace(); 
      } 
     } 
    } 
} 
1
> Below is example of wait notify 1st customer is trying to withdrawal 
> money 2000 but account is having only 1000 Rs so wait for deposit, 
> once deposit is completed then customer will able to withdrawal 
> amount ..till deposit customer is waiting. 

package com.thread.example; 

class Cust{ 

    private int totalAmount=1000; 

    public synchronized void withdrwl(int amount){ 
     System.out.println("Total amount "+totalAmount +" withdrwling amount "+amount); 
     if(this.totalAmount<amount){ 
      System.out.println("not enogh amount..waiting for deposite.."); 
      try{wait();}catch(Exception e){} 
     } 
     this.totalAmount-=amount;  
     System.out.println("Withrawl successful..Remaining balance is "+totalAmount); 

    } 

    public synchronized void deposite(int amount){ 
     System.out.println("Depositing amount "+amount); 
     this.totalAmount+=amount; 
     System.out.println("deposit completed...and Now totalAmount is "+this.totalAmount); 
     notify(); 
    } 
} 

class Depo implements Runnable{ 
    Cust c; int depo; 
    Depo(Cust c, int depo){ 
     this.c=c; 
     this.depo=depo; 

    } 

    @Override 
    public void run() { 
    c.deposite(depo); 

    } 

} 
class Withdrawl implements Runnable{ 
    Cust c; int with; 
    Withdrawl(Cust c, int with){ 
     this.c=c; 
     this.with=with; 

    } 

    @Override 
    public void run() { 
    c.withdrwl(with); 

    } 

} 

public class MainClass { 

    public static void main(String[] args) { 
     Cust c = new Cust(); 
     Thread w = new Thread(new Withdrawl(c, 2000)); 
     Thread d= new Thread(new Depo(c, 1000)); 
     w.start(); 
     d.start(); 


    } 

} 
1

I creado dos hilos uno para la impresión de números impares (OddThread) y otro para los números pares (EvenThread).Dentro del método de ejecución de cada uno de los hilos, utilicé el objeto compartido de la clase Imprimir para llamar a printOdd() y printEven() para Odd y EvenThread, respectivamente. Hice el objeto compartido de Imprimir estático para que solo se realice una copia. Ahora sincronizando en el objeto Imprimir, utilicé un indicador booleano de modo que cuando el hilo impar imprimiera un número impar, se enviará al estado de espera y al mismo tiempo se notificará al hilo par que se ejecutará. La lógica está escrita de tal manera que el hilo impar siempre imprimirá primero el número impar, sin importar qué, ya que el indicador se establece en falso, lo que previene inicialmente que el hilo par se ejecute y lo envíe a un estado de espera.

 package com.amardeep.test; 

     public class ThreadDemo { 
      // Shared object 
      static Print print = new Print(); 

      public static void main(String[] args) { 

       new Thread(new OddThread()).start(); 
       new Thread(new EvenThread()).start(); 

      } 
     } 

     class EvenThread implements Runnable { 

      @Override 
      public void run() { 
       ThreadDemo.print.printEven(); 

      } 

     } 

     class OddThread implements Runnable { 

      @Override 
      public void run() { 

       ThreadDemo.print.printOdd(); 
      } 

     } 

     class Print { 
      public volatile boolean flag = false; 

      public synchronized void printEven() { 

       for (int i = 1; i <= 10; i++) { 
        if (!flag) { 
         try { 
          wait(); 
         } catch (InterruptedException e) { 
          e.printStackTrace(); 
         } 
        } else { 
         if (i % 2 == 0) { 
          System.out.println("from even " + i); 
          flag = false; 
          notifyAll(); 
         } 

        } 
       } 
      } 

      public synchronized void printOdd() { 
       for (int i = 1; i <= 10; i++) { 
        if (flag) { 
         try { 
          wait(); 
         } catch (InterruptedException e) { 
          e.printStackTrace(); 
         } 
        } else { 
         if (i % 2 != 0) { 
          System.out.println("from odd " + i); 
          flag = true; 
          notifyAll(); 
         } 

        } 
       } 
      } 
     } 
    output:- 
    from odd 1 
    from even 2 
    from odd 3 
    from even 4 
    from odd 5 
    from even 6 
    from odd 7 
    from even 8 
    from odd 9 
    from even 10 
+0

¿Puedes explicar tu respuesta? Las respuestas no deben ser solo código ... – Jan

0

Qué esperar método no es, cuando un poco de hilo ejecuta un bloque sincronizado mediante el bloqueo de un objeto (que llamamos ese objeto es "a"), a continuación, dentro de ese bloque sincronizado cuando el hilo se ejecuta el método de espera de objeto " un" como esto

A a = new A(); // some class object call "a" 
    synchronized (a){ 
    a.wait();//exceptions must be handled 
} 

a continuación, el objeto se liberará y el hilo tiene que ir al estado de espera hasta que haya sido liberado de ese estado.

y otro hilo ahora pueden usar el objeto a porque es un objeto de liberación. por lo que si otro hilo bloqueado ese objeto y se ejecuta el método notificar a partir de ese objeto como

a.notify() 

Entonces uno de un hilo de los hilos que iban a estado de espera por objeto "a" puede ser liberado desde el estado de espera. De otro modo, cuando llame a notifyAll, todos los objetos de subproceso se liberarán de ese estado.

Cuestiones relacionadas