【问题标题】:java, why thread.wait() don't work in my codejava,为什么thread.wait()在我的代码中不起作用
【发布时间】:2015-04-29 08:51:45
【问题描述】:

我有一个剧本(线程)循环打印几段文字,并且有一个屏幕中断打印紧急文本,当屏幕中断打印时,它应该先等待剧本。 screenbreak打印所有文本后,它会通知剧本,剧本开始打印。

class ScreenPlay implements Runnable{

    public synchronized void notifys() throws InterruptedException {
      notify();
    }

    public synchronized void waits() throws InterruptedException {
      wait();
    }

    public void run(){
      for(int i=0; i<15; i++){   
          System.out.println(i);
          try{
            Thread.sleep(500); 
          }catch(InterruptedException e){
            e.printStackTrace();
          }
          if( i == 14 ){
              i = -1;
          }
      }
    }
}

class ScreenBreak implements Runnable{
  private ScreenPlay screenplay;

  public ScreenBreak(ScreenPlay screenplay){
    this.screenplay = screenplay;
  }

  public void run(){
    try{
      Thread.sleep(2000);
      screenplay.waits();
    }catch(InterruptedException e){
      e.printStackTrace();
    }
    for(int i=0; i<5; i++){
      System.out.println("@_" + i);
    }
    try{
      Thread.sleep(5000);
      screenplay.notifys();
    }catch(InterruptedException e){
      e.printStackTrace();
    }
  }

}

public class Waits {
    public static void main(String[] args) {

      ScreenPlay s = new ScreenPlay();
      ScreenBreak sb = new ScreenBreak(s);
      new Thread(s).start();
      new Thread(sb).start();

    }
}

输出显示“wait()”根本不起作用,剧本继续打印。 screenbreak 从不打印其文本。 为什么?这里有什么问题?

我修改了代码,它可以工作。

class ScreenPlay implements Runnable{

    private int waittime = 1050;
    private boolean isPause = false;

    public synchronized  void setIsPause(boolean isPause){
      this.isPause = isPause;
    }

    public synchronized void go() throws InterruptedException {
      this.isPause = false;
      notify();
    }

    public void run(){
      for(int i=0; i<15; i++){   
          System.out.println(i);
          try{
            for(int j = 0; j < waittime/500 + 1; j++){
              Thread.sleep(500); 
              synchronized(this){
                if(isPause){
                  System.out.println("waiting");
                 wait();
                }else{
                  System.out.println("..."); 
                }
              }
            }
          }catch(InterruptedException e){
            e.printStackTrace();
          }
          if( i == 14 ){
              i = -1;
          }
      }
    }
}

class ScreenBreak implements Runnable{
  private ScreenPlay screenplay;

  public ScreenBreak(ScreenPlay screenplay){
    this.screenplay = screenplay;
  }

  public void run(){
    try{
      Thread.sleep(2000);
    }catch(InterruptedException e){
      e.printStackTrace();
    } 
    screenplay.setIsPause(true);
    try{
      Thread.sleep(5000);
      for(int i=0; i<5; i++){
          System.out.println("@_" + i);
      }
      screenplay.go();
    }catch(InterruptedException e){
      e.printStackTrace();
    }

  }

}

public class Waits {
    public static void main(String[] args) {

      ScreenPlay s = new ScreenPlay();
      ScreenBreak sb = new ScreenBreak(s);
      new Thread(s).start();
      new Thread(sb).start();
      try{
        Thread.sleep(15000);
      }catch(InterruptedException e){
        e.printStackTrace();
      }
      new Thread(sb).start();

    }
}

【问题讨论】:

  • 您的waits() 方法的目的是什么?它唯一能做的就是让你写screenplay.waits()而不是写screenplay.wait()。这有什么帮助? notifys() 方法同上。
  • @james large 我怎样才能从那个线程中等待一个线程?使用 volatile 变量,当为 true 时使用 wait()。有一个sleep(),当时间长了,紧急文本不会立即打印出来。
  • @jameslarge 最重要的是它不会等待剧本。等待之前有一个同步词,我认为它们之间可能存在一些差异。
  • 糟糕!我错过了看到synchronized。我不习惯在方法名称前看到synchronized,因为 IMO 同步整个方法是不好的设计。
  • @jameslarge 感谢您的提醒。

标签: java multithreading wait notify


【解决方案1】:

ScreenBreak 开始wait()ing 时,没有人可以notify() 它。对notify() 的唯一调用是在ScreenBreak,但它永远不会到达那里,因为它被困在wait()

推荐:回tutorial

【讨论】:

  • 你的意思是 screenplay.waits() 让屏幕中断等待而不是剧本。
  • 好吧,从技术上讲,调用 wait() 会使当前线程等待(在本例中是运行 ScreenBreak 的线程)。
  • 非常感谢。你的回答非常棒。
  • 最近我一直在学习说“调用者”或“调用线程”而不是“当前线程”。自从我看到其中一个菜鸟评论,“我不明白;当系统有多个 CPU 时,Thread.getCurrentThread() 将返回哪个线程?”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-09
  • 2013-06-20
  • 1970-01-01
  • 1970-01-01
  • 2014-01-23
  • 2013-08-06
相关资源
最近更新 更多