如何告诉主线程完成线程作业的一部分

时间:2013-07-31 15:07:43

标签: java multithreading

通知是否仅在线程完成后才起作用?在下面的代码中,我无法收到通知,直到我评论为(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);
            }    
        }        
    }
}

3 个答案:

答案 0 :(得分:1)

您应该尽量避免将waitnotify与较新版本的Java一起使用,因为它们难以正确使用。尝试使用类似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);
        }          
    }
}

答案 1 :(得分:0)

如果您希望在Thread t完成时收到通知,请在调用线程中调用t.join()。这将阻止t完成其Runnable

答案 2 :(得分: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);
      }
    }
  }
}