0

通知仅在线程完成后才有效吗?在下面的代码中,直到我评论时(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 waitnotify因为它们很难正确使用。尝试使用类似 a 的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扩展Thread而不是实现Runnable,然后直接分配reader为一个新的实例SerialReader。:

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 回答