wait() および notifyAll() メソッドについて少し質問があります。コードは 2 つのスレッドの「レース」をシミュレートしています。
コードを見てみましょう - 問題は、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;
}