我正在尝试使用多线程模拟java中100米的跑步比赛程序。在这次尝试中,我创建了一个原子整数变量,该变量应该对所有线程都是通用的。每个线程越过100后,此变量应增加1.不幸的是结果不如预期。这是我对该程序的尝试。
package running;
import java.util.concurrent.atomic.*;
public class Employee implements Runnable{
AtomicInteger j = new AtomicInteger();
public void run() {
for(int i=1;i<=100;i++){
System.out.println(Thread.currentThread().getName()+" " + i);
try {
Thread.sleep(100);
}
catch (InterruptedException e) {
e.printStackTrace();
}
if(i==100)
{
System.out.println(Thread.currentThread().getName()+" is in "+j.incrementAndGet()+" place");
}
}
}
public static void main(String []args) throws Exception{
Employee e= new Employee();
Thread a= new Thread(e,"First");
Thread b= new Thread(e,"Second");
Thread c= new Thread(e,"Third");
Thread d= new Thread(e,"Fourth");
Thread f= new Thread(e,"Fifth");
a.start();
b.start();
c.start();
d.start();
f.start();
}
}
为了以可理解的方式演示我的问题,我添加了一个print语句来检查代码中线程的运行情况。这是输出的最后10行。
Second 100
Fourth 100
Third 100
Fifth 100
First 100
Fourth is in 3 place
Third is in 1 place
Second is in 2 place
Fifth is in 4 place
First is in 5 place
答案 0 :(得分:1)
我没有看到意想不到的结果。当我运行你的代码时,我得到:
First is in 1 place
Third is in 3 place
Second is in 4 place
Fifth is in 2 place
Fourth is in 5 place
如果我再次运行代码,我明白了:
First is in 1 place
Second is in 2 place
Fifth is in 4 place
Fourth is in 3 place
Third is in 5 place
如预期的那样,结果并不总是一样的。并且AtomicInteger没有丢失任何更新。
如果希望按顺序显示结果,则需要同步注册结果的代码部分。 (以确保达到100的第一个线程将在下一个线程达到100之前写入该信息),例如,见下文:
import java.util.ArrayDeque;
import java.util.Queue;
import java.util.concurrent.atomic.AtomicInteger;
public class Employee implements Runnable {
private static AtomicInteger j = new AtomicInteger();
private static Queue<String> queue = new ArrayDeque<>();
public static void main(String[] args) throws Exception {
Employee e = new Employee();
Thread a = new Thread(e, "First");
Thread b = new Thread(e, "Second");
Thread c = new Thread(e, "Third");
Thread d = new Thread(e, "Fourth");
Thread f = new Thread(e, "Fifth");
a.start();
b.start();
c.start();
d.start();
f.start();
a.join();
b.join();
c.join();
d.join();
f.join();
while (queue.size() > 0) {
System.out.println(queue.remove());
}
}
public void run() {
for (int i = 1; i <= 100; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (queue) {
if (i == 100) {
queue.add(Thread.currentThread().getName() + " is in " + j.incrementAndGet() + " place");
}
}
}
}
}