无法使用 break 语句退出循环

Can't exit for loop using break statement

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 米时打印它们的名称。请告诉我为什么会这样,我该如何纠正?

按以下方式使用 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();
    }
}

如果您不希望 "race" 在找到获胜者后继续,请在循环开头添加以下内容:

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

But what is happening with this code is that the the for loop is running until each thread reaches 5 meters and printing the name of all the threads as they reach the 5 meters. Please tell me why is this happening ...

每个线程都是 运行独立的。他们所做的只是数到 5 并打印 WINNER,他们不知道其他线程在做什么,或者是否有 "won" 在它们之前。如果您只想 一个 线程成为赢家,那么他们需要共享某种状态,以便他们知道哪个是赢家。

... and how can i correct it ?

我认为@luk2302 的答案,共享 AtomicBoolean 是解决问题的好方法。单个 AtomicBoolean 由主线程创建并传递到所有 sub-threads.

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 缓存,因此它们可以 运行 独立并获得高性能。

希望这对您有所帮助。