3

I'm using a quad core PC (Intel CORE i7) but I execute the task on 4 threads it takes 14s instead of somthing aroud 6s which is the time taken by one thread to perform the task. Is it because of all the initialisatioin (creation of the 3 other threads, ...) ?

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import junit.framework.TestResult;
import junit.framework.TestSuite;

import com.google.common.base.Stopwatch;

public class MultithreadWithExecutor {


        private static class ExecuteLongTask implements Callable<Integer>{

    private static final int ARRAY_SIZE = 10000;
    private static final int NB_TEST_ALL = 10000;
    private static final int NB_TEST_QUART = NB_TEST_ALL/4;

    @Override
    public Integer call() throws Exception {
        for (int i = 0; i < NB_TEST_QUART; i++) {
            //Create a list
            List<Double> lst = new ArrayList<Double>();
            for (int j = 0; j < ARRAY_SIZE; j++) {
                lst.add(Math.random());
            }

            //sort it
            Collections.sort(lst);

        }
        return 0;
    }

}
  public static void main(String[] ar) throws InterruptedException, ExecutionException {
        int n = 4;
        // Build a fixed number of thread pool
        ExecutorService pool = Executors.newFixedThreadPool(n);

        Stopwatch watch = Stopwatch.createStarted();
        Future<Integer> future1 = pool.submit(new ExecuteLongTask());
        Future<Integer> future2 = pool.submit(new ExecuteLongTask());
        Future<Integer> future3 = pool.submit(new ExecuteLongTask());
        Future<Integer> future4 = pool.submit(new ExecuteLongTask());

        // Wait until threads finish
        int testRuns= future1.get();
        testRuns+=future2.get();
        testRuns+=future3.get();
        testRuns+=future4.get();
        long elapsed = watch.elapsed(TimeUnit.MILLISECONDS);
// took ~14s instead of ~6s (time taken by on thread to execute the task)
        System.out.println("Runned: "+testRuns+" in: "+elapsed);
        pool.shutdown();
    }

}

ElArbi
  • 1,145
  • 3
  • 13
  • 22
  • http://stackoverflow.com/questions/2867278/why-does-this-java-code-not-utilize-all-cpu-cores/2867731#2867731 – Ted Bigham Apr 11 '14 at 09:19

1 Answers1

0

Check the following things:

  • your test is not using synchronized on a shared object
  • you don't get an Exception when adding try { (new MyTestCase("test")).runBare(); } catch (Throwable throwable) { throwable.printStackTrace(); } to your call method. If you get
    • java.lang.IllegalAccessException: Class junit.framework.TestCase can not access a member of class ...MyTestCase with modifiers "public" make the class and the classes including that class public
    • if you get junit.framework.AssertionFailedError: Method "test" not found change either the parameter to new MyTestCase("test") to reflect the name of your function or change the name of your function to test

If your problem can not be solved this way please show us a MyTestCase-class which exhibits the behaviour.

TheConstructor
  • 4,285
  • 1
  • 31
  • 52
  • I don't think synchronized is needed since no resource is shared. – ElArbi Apr 14 '14 at 06:27
  • 1
    @ElArbi synchronized is blocking parallel execution on purpose. If I don't know what's in `MyTestCase` I can't tell if the test-case itself does not want to be run multiple times in parallel. (Which would be an explanation) – TheConstructor Apr 14 '14 at 06:33
  • I have edited the code, now I don't use the test case. – ElArbi Apr 14 '14 at 09:33