How can I achieve that the while loop here is always executed exactly 100 times. When I execute the code, in rare cases it prints 99 or 98 lines on the console and not always 100, which I do not understand.
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicInteger;
public class Print implements Runnable {
static AtomicInteger atomicInteger = new AtomicInteger(0);
@Override
public void run() {
while (atomicInteger.getAndIncrement() < 100)
System.out.println(Thread.currentThread());
}
public static void main(String[] args) throws InterruptedException {
ArrayList<Thread> threads = new ArrayList<>();
for (int i = 0; i < 5; i++)
threads.add(new Thread(new Print()));
for (Thread thread : threads)
thread.start();
for (Thread thread : threads)
thread.join();
}
}
Unable to replicate your reported experience.
In my mind’s debugger, that seems correct as I cannot see any thread-safety fault in your code.
To automate further testing, I altered your code as follows. Rather than call
System.out.println
, I added the thread ID to aList
ofLong
. I made the list aCopyOnWriteArrayList
for thread-safety. I can programmatically detect if the resulting list is not exactly 100 elements in size.When run on a Mac mini (2018) 3 GHz Intel Core i5 with six real cores and no hyper-threading, and 32 GB 2667 MHz DDR4, using Java 16 within IntelliJ. Running
cycle
to a million takes about 5 minutes.ExecutorService
By the way, in modern Java we rarely need to address the
Thread
class directly. Instead, use the Executors framework added to Java 5.Here is revised version of the code above, rejiggered to use an executor service.