Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 调用notifyAll的好解决方案是什么?_Java_Multithreading_Wait_Notify - Fatal编程技术网

Java 调用notifyAll的好解决方案是什么?

Java 调用notifyAll的好解决方案是什么?,java,multithreading,wait,notify,Java,Multithreading,Wait,Notify,我有一个关于wait()和notifyAll()方法的小问题。 代码正在模拟两个线程的“竞争” 让我们看一下代码-问题是notifyAll()方法对等待的线程不执行任何操作会导致主方法首先获得锁。。。简单的解决方法是设置一些延迟(参见注释行)。但这是一种糟糕的做法。解决这个问题的好办法是什么?我只希望使用wait/notifyAll/join方法 public class TestThreads { public static void main(String[] args) throws

我有一个关于wait()和notifyAll()方法的小问题。 代码正在模拟两个线程的“竞争”

让我们看一下代码-问题是notifyAll()方法对等待的线程不执行任何操作会导致主方法首先获得锁。。。简单的解决方法是设置一些延迟(参见注释行)。但这是一种糟糕的做法。解决这个问题的好办法是什么?我只希望使用wait/notifyAll/join方法

public class TestThreads {
  public static void main(String[] args) throws InterruptedException {
    System.out.println("_start main");
    Object lock = new Object();
    Thread t1 = new Thread(new Car("Red car", lock));
    Thread t2 = new Thread(new Car("Black car", lock));
    t1.start();
    t2.start();
    //Thread.sleep(10L);
    synchronized (lock){
      System.out.println("Let`s go!");
      lock.notifyAll();
    }
    t1.join();
    t2.join();
    System.out.println("_exiting from main...");
  }
}

class Car implements Runnable {
  private final String name;
  private final Object lock;

  public Car(String name, Object lock) {
    this.name = name;
    this.lock = lock;
  }

  @Override
  public void run() {
    int distance = 100;
    synchronized (lock){
      try{
        System.out.println(name + " waiting...");
        lock.wait();
      }catch (InterruptedException e){
        e.printStackTrace();
      }
    }
    System.out.println(name + " started...");
    while (distance != 0){
      try{
        Thread.sleep((long) (100 * Math.random()));
      }catch (InterruptedException e){
        e.printStackTrace();
        break;
      }
      distance--;
      if (distance % 20 == 0 && distance != 0){
        System.out.println(name + " " + distance+ " miles left");
      }

      else if (distance == 0){
        System.out.println(name + " finished race!!!");
      }
    }
    System.out.println("_exiting from thread of " + name + " move simulation...");
  }
}
对不起,我的英语不好

谢谢你的回答。 那么,这个解决方案更好吗

public class TestThreads {
  public static void main(String[] args) throws InterruptedException {
    System.out.println("_start main");
    LightSignal lock = new LightSignal();
    Thread t1 = new Thread(new Car("Red car", lock));
    Thread t2 = new Thread(new Car("Black car", lock));
    t1.start();
    t2.start();
    synchronized (lock){
      Thread.sleep(1000L);
      lock.isGreen = true;
      System.out.println("Let`s go!");
      lock.notifyAll();
    }
    t1.join();
    t2.join();
    System.out.println("_exiting from main...");
  }
}

class Car implements Runnable {
  private final String name;
  private final LightSignal lock;

  public Car(String name, LightSignal lock) {
    this.name = name;
    this.lock = lock;
  }

  @Override
  public void run() {
    int distance = 100;
    synchronized (lock){
      try{
        while (!lock.isGreen){
          System.out.println(name + " waiting...");
          lock.wait();
        }
      }catch (InterruptedException e){
        e.printStackTrace();
      }
    }
    System.out.println(name + " started...");
    while (distance != 0){
      try{
        Thread.sleep((long) (100 * Math.random()));
      }catch (InterruptedException e){
        e.printStackTrace();
        break;
      }
      distance--;
      if (distance % 20 == 0 && distance != 0){
        System.out.println(name + " " + distance + " miles left");
      }
    }
    System.out.println(name + " finished race!!!");
    System.out.println("_exiting from thread of " + name + " move simulation...");
  }
}

class LightSignal {
  public boolean isGreen = false;
}
调用notifyAll()时,需要更改状态;在等待()时,需要在循环中检查该状态。如果你不这样做

  • notifyAll()只通知正在等待()的线程,而不通知稍后开始等待的线程
  • wait()可能会错误地醒来
在这种情况下,最简单的解决方法就是不用担心它。你正在等待一个高达100毫秒的随机延迟,因此尝试同步这样一个随机系统的启动显然不会有多大区别


当循环退出时,我认为“比赛结束了”,您不需要为此使用
if
子句。

您使用wait/notify的决定是错误的。您需要围绕这些原始原语进行更多编程,以获得可靠的行为。对于初学者,必须等待条件,而不是原始的
notifyAll
信号。例如,这在网络上都有记录。