1

I was reading about thread pools and found that thread creation is considered an expensive process. This counteracted my intuition and I decided to put it to test:

public static void main(String[] args) {
    long start = System.currentTimeMillis();
    for (int i = 0; i < 1000; i++) {
        new Thread(new Runnable() {
            @Override
            public void run() {
            }
        }).start();
    }
    long end = System.currentTimeMillis();
    System.out.println(end - start + "ms");
}

This prints 696ms on my system. So the time to create one thread is close to 0.69 millisecond. Why is this considered slow?

Edit:

public class Test {
    static int a = 1;
    static long start;
    static void setA() {
        ++a;
        if(a>=1000) {
            long end = System.currentTimeMillis();
            System.out.println(end - start + "ms");
        }
    }

    public static void main(String[] args) {
        start = System.currentTimeMillis();
        for (int i = 0; i <= 1000; ++i) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    setA();
                }
            }).start();
        }
    }
}

This prints 729ms.

Kshitiz Sharma
  • 17,947
  • 26
  • 98
  • 169
  • 4
    Well for one thing you've only measured the time taken on the main thread. You haven't waited for the threads to actually start... Also, a millisecond is a pretty long time in computing. – Jon Skeet Apr 07 '14 at 07:23
  • @JonSkeet Please see the modified code. Would say that now actual time to start is included in consideration? – Kshitiz Sharma Apr 07 '14 at 07:33
  • @JonSkeet `Also, a millisecond is a pretty long time` If I have 100 threads I'd save `100ms` by converting to thread pool. To me this sort of optimization doesn't make sense for most enterprise applications. – Kshitiz Sharma Apr 07 '14 at 07:40
  • 1
    @KshitizSharma: It depends - if you're considering creating a new thread per request in a server, then you're basically saying that to handle 1000 requests per second, you'd be spending *all* the time creating threads. – Jon Skeet Apr 07 '14 at 08:03

3 Answers3

3

When people talk about thread creation being slow, it is generally relative to the amount of work the thread is doing.

Try benchmarking a computational task, such as adding 100 numbers together, and compare how long that takes with thread creation (once you can measure it accurately).

merlin2011
  • 71,677
  • 44
  • 195
  • 329
  • This is the best answer. "...relative to the amount of work the thread is doing." If your program spends hundreds of milliseconds to create a thread that will only do a few microseconds worth of work, then you probably should look for a more efficient solution to your problem. – Solomon Slow Apr 07 '14 at 13:29
0

There are a few factors why this is slow. First, the start method calls a native method, and native calls are always slow. Then, creating a thread is a kernel function (allocating memory for it, adding it to the scheduler), so the program has to wait for the thread actually being created.

maxdev
  • 2,491
  • 1
  • 25
  • 50
  • This explains how they work internally not why `0.72 ms` for a thread is considered slow. – Kshitiz Sharma Apr 07 '14 at 07:37
  • Hmm, it's not considered slow in general, but you have to take care for what purpose you do it. E.g. it does not make any sense to create a thread simply to let a calculation run threaded if it's not really necessary.. – maxdev Apr 07 '14 at 08:34
  • Can you quote some statistics that native method calls are slow? The JVM makes native calls all of the time so I don't think that's true. – Gray Apr 07 '14 at 13:04
  • The calling itself is "slow", because the VM has to do some steps before calling the method: create a native frame on the VM stack, add the parameters that were pushed by the Java code (which is calling the native method) as local references to that native frame, also push the values on the native stack, CALL into the native method, clean the stack, and then free the native VM frame with it's local references. Source is a VM under development by a friend of mine and me. – maxdev Apr 07 '14 at 16:17
0

Every time you create a thread in your program, the virtual machine(VM) and the operating system has to allocate a bunch of data structures to keep track of the execution and context switching among these threads. For example, each thread will have its own stack, its local variables, thread local variables and so on. If it is a green thread, the VM will allocate and manage these data structures. If it is a native thread, the operating system will manage them. In either case, you end up allocating system resources to manage the threads. This is why creating a thread takes a little time and creating a lots of threads may consume a good amount of system resources.

Indra
  • 471
  • 3
  • 5