gpt4 book ai didi

java - 调用notifyAll有什么好的解决方案吗?

转载 作者:行者123 更新时间:2023-12-01 14:37:00 25 4
gpt4 key购买 nike

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

让我们看一下代码 - 问题是,notifyAll() 方法对等待线程不执行任何操作,导致 main 方法首先获得锁...简单的解决方案是设置一些延迟(请参阅注释行)。但这是一个不好的做法。这个问题有什么好的解决办法吗?我希望仅使用 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...");
}
}
PS。抱歉我的英语不好。

谢谢您的回答。那么,这个解决方案是不是更好呢?

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()时,你需要改变一个状态,当你在waiting()时,你需要循环检查该状态。如果您不这样做

  • notifyAll() 只通知正在 waiting() 的线程,而不通知稍后开始等待的线程。
  • wait() 可能会被虚假唤醒。

在这种情况下,最简单的解决方案就是不要担心。您正在等待长达 100 毫秒的随机延迟,因此尝试同步此类随机系统的启动不太可能产生太大影响。

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

关于java - 调用notifyAll有什么好的解决方案吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16400414/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com