1
public class Demo {
    public Demo() {
        long start = System.nanoTime();
        new Thread(() ->{});
        System.out.println(System.nanoTime()-start);

        start = System.nanoTime();
        new Thread(() ->{});
        System.out.println(System.nanoTime()-start);
    }

    public static void main(String[] args) throws InterruptedException {
        new Demo();
    } 
}

output:

    35911135
    245483

Can someone explain to me what's going on behind the scenes of new Thread(() ->{});? I would like for both of these to execute at the same speed and have tried loading the Runnable class into memory in my main method with no results.

Why is the first execution slower than the second?

bonus question (answer only if there's an immediately apparant explanation): When these exact lines are run as part of my larger code base, my average execution time is approx. 60 ms, as opposed to the above demonstrated 35ms. Why might this be?

user2651804
  • 1,464
  • 4
  • 22
  • 45
  • 3
    Obligatory reading: [*How do I write a correct micro-benchmark in Java?*](https://stackoverflow.com/questions/504103/how-do-i-write-a-correct-micro-benchmark-in-java). – Oliver Charlesworth Jul 05 '17 at 16:41
  • 1
    Since you don't start the `Thread`(s), they don't do anything. You're instantiating object instances. – Elliott Frisch Jul 05 '17 at 16:43
  • The time that this program will take to complete is entirely arbitrary, as you're not even calling `Thread#start` on the threads that you define. – Jacob G. Jul 05 '17 at 16:44
  • I find it very hard to believe that the *average* execution time of `new Thread(() ->{})` is 35-60 ms. For me, a simple loop of 20 iterations shows 39 ms for first iteration, but around **0.007 ms** for the other 19 iterations. Once JIT kicks in, it gets down to **0.0008 ms**. – Andreas Jul 05 '17 at 16:50
  • 1
    @Andreas: indeed, you can assume that >30ms of that stem from the very first lambda expression instantiation, as it implies loading and initialization of roughly 150 classes, from the `java.lang.invoke` framework as well as the internally used ASM library. But here, even some core and Collection API classes need to be loaded at this point, which surely would be already in use in real life applications. As even the OP already showed, it needs only 0.2ms for the second lambda expression which will still get a freshly generated class (but doesn’t need to load the framework again). – Holger Jul 05 '17 at 17:16

0 Answers0