Reputation: 95
I am trying to simulate a 100 m running race program in java using multithreading. In this attempt I made a Atomic integer variable which should be common to all threads. This variable should increase by 1 after each thread crosses 100. unfortunately the result is not as expected.This is my attempt at the program.
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();
}
}
To demonstrate my problem in an understandable way I have added a print statement to check the running of the threads in the code . Here is the last 10 lines of the output.
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
Upvotes: 0
Views: 72
Reputation: 725
I don't see unexpected results. when I run your code I get:
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
if I run the code again, I get this:
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
as expected, the results are not always the same. and the AtomicInteger is not losing any update.
if you want the results to be displayed in order, you need to synchronize the part of the code that registers the results. (to make sure that the first thread that reaches 100 will write that information before the next thread reaches 100) for example, see below:
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");
}
}
}
}
}
Upvotes: 1