Warm tip: This article is reproduced from serverfault.com, please click

Running single java thread is faster than main?

发布于 2020-11-28 14:51:47

im doing a few concurrency experiments in java. I have this prime calculation method, which is just for mimicking a semi-expensive operation:

static boolean isprime(int n){
    if (n == 1)
        return false;
    boolean flag = false;
    for (int i = 2; i <= n / 2; ++i) {
        if (n % i == 0) {
            flag = true;
            break;
        }
    }
    return ! flag;
}

And then I have this main method, which simply calculates all prime number from 0 to N, and stores results in a array of booleans:

public class Main {

public static void main(String[] args) {
    final int N = 100_000;
    int T = 1;

    boolean[] bool = new boolean[N];
    ExecutorService es = Executors.newFixedThreadPool(T);

    final int partition = N / T;


    long start = System.nanoTime();

    for (int j = 0; j < N; j++ ){
        boolean res = isprime(j);
        bool[j] = res;
    }            
    System.out.println(System.nanoTime()-start);
}

This gives me results like: 893888901 n/s 848995600 n/s

And i also have this drivercode, where I use a executorservice where I use one thread to do the same:

public class Main {

public static void main(String[] args) {
    final int N = 100_000;
    int T = 1;

    boolean[] bool = new boolean[N];
    ExecutorService es = Executors.newFixedThreadPool(T);

    final int partition = N / T;

    long start = System.nanoTime();


    for (int i = 0; i < T; i++ ){
        final int current = i;
        es.execute(new Runnable() {
            @Override
            public void run() {
                for (int j = current*partition; j < current*partition+partition; j++ ){
                    boolean res = isprime(j);

                    bool[j] = res;
                }

            }
        });
    }

    es.shutdown();
    try {
        es.awaitTermination(1, TimeUnit.MILLISECONDS);
    } catch (Exception e){
        System.out.println("what?");
    }

    System.out.println(System.nanoTime()-start);
}

this gives results like: 9523201 n/s , 15485300 n/s.

Now the second example is, as you can read, much faster than the first. I can't really understand why that is? should'nt the exercutorservice thread (with 1 thread) be slower, since it's basically doing the work sequentially + overhead from "awaking" the thread, compared to the main thread?

I was expecting the executorservice to be faster when I started adding multiple threads, but this is a little counterintuitive.

Questioner
n00bster
Viewed
0
donttrythat 2020-11-28 23:13:51

It's the timeout at the bottom of your code. If you set that higher you arrive at pretty similar execution times.

es.awaitTermination(1000, TimeUnit.MILLISECONDS);

The execution times you mention for the first main are much higher than the millisecond you allow the second main to wait for the threads to finish.