0

スレッドが終了した後にのみ通知が機能するというのは本当ですか? 以下のコードでは、while (true) をコメントするまで通知を受け取ることができません。スレッドジョブの一部が完了したことをメインスレッドに伝える方法は?

public class ThreadMain {
    public Thread reader;
    private class SerialReader implements Runnable {
        public void run() {
            while (true) {
                try {
                    Thread.sleep(3000);                
                    synchronized(this) {
                        System.out.println("notifying");
                        notify();
                        System.out.println("notifying done");
                    }                
                } catch (Exception e) {
                    System.out.println(e);
                }                
            }
        }
    }

    ThreadMain() {
        reader = new Thread(new SerialReader());
    }

    public static void main(String [] args) {
        ThreadMain d= new ThreadMain();    
        d.reader.start();
        synchronized(d.reader) {
            try {    
                d.reader.wait();
                System.out.println("got notify");
            } catch (Exception e) { 
                System.out.println(e);
            }    
        }        
    }
}
4

3 に答える 3

1

新しいバージョンの Java を正しく使用するのは難しいため、それらをwait使用することは避けてください。代わりにnotifya のようなものを使用してみてくださいBlockingQueue

public class ThreadMain {
    public final BlockingQueue<Boolean> queue = new LinkedBlockingQueue<>();
    private class SerialReader implements Runnable {
        public void run() {
            while (true) {
                try {
                    Thread.sleep(3000);                
                    System.out.println("notifying");
                    queue.offer(Boolean.TRUE);
                    System.out.println("notifying done");            
                } catch (Exception e) {
                    System.out.println(e);
                }                
            }
        }
    }

    ThreadMain() {
        reader = new Thread(new SerialReader());
    }

    public static void main(String [] args) {
        ThreadMain d= new ThreadMain();    
        d.reader.start();
        try {    
            d.queue.take(); // block until something is put in the queue
            System.out.println("got notify");
        } catch (Exception e) { 
            System.out.println(e);
        }          
    }
}
于 2013-07-31T15:15:30.153 に答える
0

Thread t完了時に通知を受け取りたい場合t.join()は、呼び出しスレッドを呼び出します。tこれは、が終了するまでブロックされますRunnable

于 2013-07-31T15:25:38.473 に答える
0

コメントでユーザーの奇数が指摘されているように、あなたは別のオブジェクトを呼び出しwait()ています。notify()これに対する可能な修正は、実装するのではなくSerialReader拡張してから、直接の新しいインスタンスになるように割り当てることです。:ThreadRunnablereaderSerialReader

public class ThreadMain {
    public Thread reader;
    private class SerialReader extends Thread {
        public void run() {
            while (true) {
                try {
                    Thread.sleep(3000);                
                    synchronized(this) {
                        System.out.println("notifying");
                        notify();
                        System.out.println("notifying done");
                    }                
                } catch (Exception e) {
                    System.out.println(e);
                }                
            }
        }
    }

    ThreadMain() {
        reader = new SerialReader();
    }

    public static void main(String [] args) {
        ThreadMain d= new ThreadMain();    
        d.reader.start();
        synchronized(d.reader) {
            try {    
                d.reader.wait();
                System.out.println("got notify");
            } catch (Exception e) { 
                System.out.println(e);
            }    
        }        
    }
}

/Runnableと一緒に使用したい場合は、次の方法で実行できます。wait()notify()

public class ThreadMain {

  public Thread reader;

  private class SerialReader implements Runnable {

    public void run() {
      Thread thisThread = Thread.currentThread();

      while (true) {
        try {
          Thread.sleep(3000);
          synchronized (thisThread) {
            System.out.println("notifying");
            thisThread.notify();
            System.out.println("notifying done");
          }
        } catch (Exception e) {
          System.out.println(e);
        }
      }
    }
  }

  ThreadMain() {
    reader = new Thread(new SerialReader());
  }

  public static void main(String[] args) {
    ThreadMain d = new ThreadMain();
    d.reader.start();
    synchronized (d.reader) {
      try {
        d.reader.wait();
        System.out.println("got notify");
      } catch (Exception e) {
        System.out.println(e);
      }
    }
  }
}
于 2013-07-31T15:28:50.490 に答える