2011-12-02 50 views
8

Ai cũng có thể cung cấp cho tôi một ví dụ nhỏ minh họa hàm wait() và notify() trong java. Tôi đã thử với đoạn mã dưới đây nhưng nó không hiển thị những gì tôi mong đợi.Một ví dụ nhỏ để minh họa phương thức wait() và notify() trong 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) { 

      } 

     } 
    } 
} 

Vấn đề là phương pháp trong lớp WaitDemo không nhận được thực hiện và theo ý tưởng của tôi SOP sau khi chờ đợi() nên thực hiện. Xin hãy giúp tôi về điều này.

+6

Đó không phải là những gì Google dành cho? – mre

+7

@ Крысa: Hãy nhớ rằng một trong những mục tiêu của SO là trở thành hit hàng đầu trên Google (và các tìm kiếm khác). Đây là một câu hỏi hoàn toàn hợp lý. Nó nên được trả lời với một ví dụ - ở đây, trên SO, không phải ở nơi khác - và thảo luận (lý tưởng) về nơi Sourav đã đi sai ở trên. –

+2

Hành vi mong đợi của chương trình này là gì? – GETah

Trả lời

3

Bạn có hai cấp ngoặc nhọn { trong khối try của mình. Nếu bạn loại bỏ bộ bên trong (có vẻ như không làm gì cả), điều đó có khắc phục được sự cố không?

Có một số ví dụ xung quanh, tất cả đều minh họa cách sử dụng. Liên kết cuối cùng là tập hợp các kết quả có thể giúp bạn. Nếu bạn cần thêm thông tin cụ thể, hãy cho tôi biết ứng dụng của bạn đang cố gắng làm gì và tôi có thể tìm các ví dụ cụ thể hơn cho tình huống của bạn.

0

Vấn đề của bạn là bạn đang tạo ra hai trường hợp của lớp Thread. Vì vậy, khi wait() được gọi, nó nằm trên hai trường hợp khác nhau, không phải trong số đó có một chủ đề khác là tranh chấp cho màn hình của bạn, cũng không có một luồng khác để gọi notifyAll() để đánh thức luồng từ trạng thái chờ của nó.

Vì vậy, mỗi chuỗi bạn đã bắt đầu sẽ đợi mãi mãi (hoặc cho đến khi bị gián đoạn vì một số lý do khác).

Bạn muốn có nhiều luồng truy cập cùng một màn hình, vì vậy hãy bắt đầu bằng cách cố gắng mã hóa mã gì đó trong đó không thực sự là một chuỗi, nhưng chỉ đơn giản là được sử dụng bởi một chuỗi.

@normalocity đã cung cấp liên kết đến nhiều ví dụ.

0

Tôi vừa cập nhật this answer để bao gồm SCCE.

Dừng công nhân gọiNếu được thực hiện trên WorkerPauseManager. Nếu người quản lý bị tạm dừng khi thread công nhân gọi pauseIfNeeded(), chúng ta gọi wait(), cho biết thread đang chờ đợi cho đến khi một thread khác gọi notify() hoặc notifyAll() trên đối tượng đang chờ. Điều này xảy ra khi Swing Event Dispatch Thread gọi play() trên trình quản lý, mà lần lượt gọi notifyAll().

Lưu ý rằng bạn phải có khóa được đồng bộ hóa trên đối tượng bạn đang gọi wait() hoặc thông báo() bật. Vì các phương thức trong WorkerPauseManager được đồng bộ hóa, tất cả các phương thức đồng bộ đều nhận được khóa đồng bộ trên chính 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

Tôi tạo ra hai luồng một cho in số lẻ (OddThread) và một cho số chẵn (EvenThread).Bên trong phương thức chạy của mỗi chủ đề tôi đã sử dụng đối tượng chia sẻ của lớp Print để gọi printOdd() và printEven() cho tương ứng Odd và EvenThread. Tôi đã tạo đối tượng được chia sẻ là In tĩnh để chỉ có một bản sao được tạo. Bây giờ đồng bộ hóa trên đối tượng Print tôi đã sử dụng một cờ Boolean sao cho khi chuỗi lẻ được in một số lẻ nó sẽ được gửi vào trạng thái chờ và đồng thời thông báo cho chuỗi thậm chí để thực thi. Logic được viết theo cách mà các chuỗi lẻ sẽ luôn luôn in số lẻ đầu tiên không có vấn đề gì, như cờ được thiết lập để sai ban đầu ngăn chặn thread thậm chí để thực hiện và gửi nó đến một trạng thái chờ đợi.

 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

Bạn có thể giải thích câu trả lời của bạn không? Câu trả lời không nên chỉ là mã ... – Jan

0

chờ gì phương pháp, không có gì, khi một số chủ đề thực hiện một khối đồng bộ bằng cách khóa một số đối tượng (chúng ta gọi là đối tượng đó là "a"), sau đó bên trong khối đồng bộ khi thread thực hiện phương pháp chờ đợi của đối tượng " a "như thế này

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

Sau đó, đối tượng sẽ nhả ra và chuỗi phải chuyển sang trạng thái chờ cho đến khi nó được giải phóng khỏi trạng thái đó.

và chuỗi anothet bây giờ có thể sử dụng đối tượng beacause đối tượng phát hành của nó. vì vậy nếu thread khác khóa đối tượng đó và nó thực hiện các thông báo phương pháp từ đối tượng đó như

a.notify() 

Sau đó, một trong những chủ đề của chủ đề mà đứng đó chờ nhà nước bởi đối tượng "a" có thể được phát hành từ trạng thái chờ đợi. Khác khôn ngoan khi gọi notifyAll sau đó tất cả các đối tượng thread sẽ phát hành từ trạng thái đó.

Các vấn đề liên quan