无法使用 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 缓存,因此它们可以 运行 独立并获得高性能。
希望这对您有所帮助。
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 缓存,因此它们可以 运行 独立并获得高性能。
希望这对您有所帮助。