Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java For loop using int vs long

Context

I am reading a tech document which basically tells me the difference between using int vs long in fori loop: Scenario A(int fori loop)

public class SafePoint {

    public static AtomicInteger num = new AtomicInteger(0);

    public static void main(String[] args) throws InterruptedException {
        Runnable runnable=()->{
            for (int i = 0; i < 1000000000; i++) {
                num.getAndAdd(1);
            }
            System.out.println(Thread.currentThread().getName()+"end!");
        };

        Thread t1 = new Thread(runnable);
        Thread t2 = new Thread(runnable);
        t1.start();
        t2.start();
        Thread.sleep(1000);
        System.out.println("num = " + num);
    }

}

Expected Result:

Thread-1end!
Thread-0end!
num = 2000000000

Scenario B(long fori loop)

public class SafePoint {

    public static AtomicInteger num = new AtomicInteger(0);

    public static void main(String[] args) throws InterruptedException {
        Runnable runnable=()->{
            for (long i = 0; i < 1000000000; i++) {
                num.getAndAdd(1);
            }
            System.out.println(Thread.currentThread().getName()+"end!");
        };

        Thread t1 = new Thread(runnable);
        Thread t2 = new Thread(runnable);
        t1.start();
        t2.start();
        Thread.sleep(1000);
        System.out.println("num = " + num);
    }

}

Expected Result:
num = 55406251 (or some random number less than 2000000000)
Thread-1end!
Thread-0end!

The most important concept he gives is the safepoint: We have safepoint in long fori loop due to uncounted loop but not int fori loop. Therefore in int fori loop, the sleep needs to wait for the two threads to finish and then do GC cause there is no safepoint when the threads are still in int fori loop.

Issue:

I take his idea and try to reproduce them on my local machine then it failed: Basically no matter whether I use int or long, it is always the result similar to the second one. The num get printed first.

Then after carefully thinking, it can only be due to the JVM I use: java 11 corretto.

Based on tech doc's idea, it basicaly means in Java 11 safepints exist both in counted and uncounted loop

Question:

Can anyone test on java 8 and tell me whether that is the reason?

I actually already tested: in java 8 we can observe the expected results of both A and B

Does java 11 change the way how we put Safe Points and why?

Related links:

The tech doc trying to explain on and How to do GC in fori loop: Why Thread.sleep(0) can prevent gc in rocketmq?

like image 760
Stan Peng Avatar asked Oct 27 '25 21:10

Stan Peng


1 Answers

The reasons of the delayed println are explained in this answer. In short, HotSpot JIT eliminated the safepoint poll inside the counted loop, so the JVM cannot reach a safepoint while the loop is running.

To eliminate a safepoint poll from the loop, two conditions must be met:

  1. the loop is counted, i.e. has a finite number of iterations ensured by an integer counter variable, and
  2. -XX:UseCountedLoopSafepoints option is disabled.

These conditions depend on the JVM version and the command line flags.

In JDK 8, a for-loop with int variable is considered counted, while a loop with long variable is not. UseCountedLoopSafepoints is always off, unless enabled explicitly with -XX:+UseCountedLoopSafepoints.

Since JDK 10, JIT compiler got the Loop Strip Mining feature. This optimization significantly reduces the overhead of safepoint polling in a tight loop, and because of that, -XX:+UseCountedLoopSafepoints became enabled by default1. That's why you don't observe a delay in JDK 11.


1 Unless a user selects Parallel or Serial GC. Since these garbage collectors are not focused on low pauses, the JVM prefers throughput and thus does not enable UseCountedLoopSafepoints. It can be still enabled manually with -XX:+UseCountedLoopSafepoints.

like image 53
apangin Avatar answered Oct 29 '25 12:10

apangin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!