[英]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();
}
}
如果您不希望在找到獲勝者后繼續“比賽”,則在循環的開頭添加以下內容:
if (raceFinished.get()) {
break;
}
但是這段代碼發生的事情是 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 緩存,因此它們可以獨立運行並獲得高性能。
希望這可以幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.