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米时打印所有线程的名称。请告诉我为什么会发生这种情况,我该如何纠正呢?
答案 0 :(得分:0)
如何以下列方式使用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();
}
}
如果你不想参加&#34;比赛&#34;在找到胜利者后继续,然后在循环开始时添加以下内容:
if (raceFinished.get()) {
break;
}
答案 1 :(得分:0)
但是这个代码发生的事情是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缓存,因此它们可以独立运行并获得高性能。
希望这有帮助。