无法使用中断语句退出循环


public class Threading extends Thread {
@Override
public void run(){
for (int i=0;i<=5;i++){
System.out.println(Thread.currentThread().getName()+" reached "+i+" metres");
if(i==5){
System.out.println("WINNER IS  "+Thread.currentThread().getName().toUpperCase(Locale.ENGLISH));              
break;
}
}
}
public static void main(String[] args) {
Threading t1=new Threading();
Threading t2=new Threading();
Threading t3=new Threading();
t1.setName("Mohit");
t2.setName("Hary");
t3.setName("Himanshu");
t1.start();
t2.start();
t3.start();
}
}

我想打印先到达5米的线程的名称,然后再退出循环。但这段代码发生的情况是,for循环一直运行,直到每个线程达到5米,并在达到5米时打印所有线程的名称。请告诉我为什么会发生这种情况,我该如何纠正?

但这段代码发生的情况是,for循环一直运行到每个线程达到5米,并在达到5米时打印所有线程的名称。请告诉我为什么会发生这种事。。。

每个线程都是独立运行的。他们所做的只是计数到5并打印WINNER,他们不知道其他线程在做什么,也不知道是否有线程在他们之前"获胜"。如果你只想让一个线程成为赢家,那么他们需要共享某种状态,这样他们就知道哪一个是赢家。

。。。我该如何纠正?

我认为@luk2302的答案,带有共享的AtomicBoolean是纠正问题的好方法。单个AtomicBoolean由主线程创建并传递到所有子线程中。

final AtomicBoolean raceFinished = new AtomicBoolean(false);
Threading t1 = new Threading(raceFinished);
Threading t2 = new Threading(raceFinished);
Threading t3 = new Threading(raceFinished);

然后,当每个线程运行到循环的末尾时,只有一个线程能够将AtomicBoolean设置为true并声明自己为胜利者。

for (int i = 0; i < 5; i++) {
// ...
}
// i == 5 here
// this is an atomic operation and will succeed only for 1 thread
if (raceFinished.compareAndSet(false, true)) {
// this is only printed if raceFinished was false beforehand
System.out.println("WINNER IS  " + Thread.currentThread().getName());
}

这是怎么回事?单个AtomicBoolean在所有线程之间共享。它的内部是一个volatile boolean字段和逻辑,以确保布尔值的原子更新。volatile设置了内存屏障,以便线程可以适当地查看和更新共享布尔字段。这一点之所以重要,是因为线程程序的性能严重依赖于本地CPU缓存,因此它们可以独立运行并获得高性能。

希望这能有所帮助。

以以下方式使用AtomicBoolean怎么样:

public static class Threading extends Thread {
private AtomicBoolean raceFinished;
public Threading(AtomicBoolean raceFinished) {
this.raceFinished = raceFinished;
}
@Override
public void run() {
for (int i = 0; i <= 5; i++) {
System.out.println(Thread.currentThread().getName() + " reached " + i + " metres");
if (i == 5) {
if (raceFinished.getAndSet(true)) {
break;
}
System.out.println("WINNER IS  " + Thread.currentThread().getName().toUpperCase(Locale.ENGLISH));
break;
}
}
}
public static void main(String[] args) {
AtomicBoolean raceFinished = new AtomicBoolean(false);
Threading t1 = new Threading(raceFinished);
Threading t2 = new Threading(raceFinished);
Threading t3 = new Threading(raceFinished);
t1.setName("Mohit");
t2.setName("Hary");
t3.setName("Himanshu");
t1.start();
t2.start();
t3.start();
}
}

如果你不想在找到获胜者后继续"比赛",那么在循环的开头添加以下内容:

if (raceFinished.get()) {
break;
}

最新更新