18

As of my understanding I have written the simple single and multithreading program below to check the execution speed. But my single-threaded program executing faster than multithreaded, kindly see the below program and mention if anything is wrong.

Single Thread:

import java.util.Calendar;

public class NormalJava {
    public static void main(String[] args) {
        System.out.println("Single Thread");
        int a = 1000;
        int b = 200;
        NormalJava nj = new NormalJava();
        nj.Add(a, b);
        nj.Sub(a, b);
        nj.Mul(a, b);
        nj.Div(a, b);
        Calendar lCDateTime = Calendar.getInstance();
        System.out.println("Calender - Time in milliseconds :"
                + lCDateTime.getTimeInMillis());

    }

    private void Add(int a, int b) {
        System.out.println("Add :::" + (a + b));
    }

    private void Sub(int a, int b) {
        System.out.println("Sub :::" + (a - b));
    }

    private void Mul(int a, int b) {
        System.out.println("Mul :::" + (a * b));
    }

    private void Div(int a, int b) {
        System.out.println("Mul :::" + (a / b));
    }
}

Output:
Single Thread
Add :::1200
Sub :::800
Mul :::200000
Mul :::5
Calender - Time in milliseconds :138 415 866 7863


Multithreaded Program:

package runnableandcallable;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
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 java.util.concurrent.TimeoutException;

public class MainThread {

    private static ExecutorService service = Executors.newFixedThreadPool(10); // connection
                                                                               // pool
    @SuppressWarnings("unchecked")
    public static void main(String[] args) throws InterruptedException {
        System.out.println("Multithreading");
        MainThread mt = new MainThread();
        mt.testThread(1000, 200);
        Calendar lCDateTime = Calendar.getInstance();
        System.out.println("Calender - Time in milliseconds :"
                + lCDateTime.getTimeInMillis());
    }

    public void testThread(final int a, final int b) {
        // create a callable for each method
        Callable<Void> callableAdd = new Callable<Void>() {
            @Override
            public Void call() throws Exception {
                Add(a, b);
                return null;
            }
        };

        Callable<Void> callableSub = new Callable<Void>() {
            @Override
            public Void call() throws Exception {
                Sub(a, b);
                return null;
            }
        };

        Callable<Void> callableMul = new Callable<Void>() {
            @Override
            public Void call() throws Exception {
                Mul(a, b);
                return null;
            }
        };

        Callable<Void> callableDiv = new Callable<Void>() {
            @Override
            public Void call() throws Exception {
                Div(a, b);
                return null;
            }
        };

        // add to a list
        List<Callable<Void>> taskList = new ArrayList<Callable<Void>>();
        taskList.add(callableAdd);
        taskList.add(callableSub);
        taskList.add(callableMul);
        taskList.add(callableDiv);

        // create a pool executor with 3 threads
        ExecutorService executor = Executors.newFixedThreadPool(3);

        try {
            // start the threads
            List<Future<Void>> futureList = executor.invokeAll(taskList);

            for (Future<Void> voidFuture : futureList) {
                try {
                    // check the status of each future. get will block until the
                    // task
                    // completes or the time expires
                    voidFuture.get(100, TimeUnit.MILLISECONDS);
                } catch (ExecutionException e) {
                    System.err
                            .println("Error executing task " + e.getMessage());
                } catch (TimeoutException e) {
                    System.err.println("Timed out executing task"
                            + e.getMessage());
                }

            }

        } catch (InterruptedException ie) {
            // do something if you care about interruption;
        }

    }

    private void Add(int a, int b) {
        System.out.println("Add :::" + (a + b));
    }

    private void Sub(int a, int b) {
        System.out.println("Sub :::" + (a - b));
    }

    private void Mul(int a, int b) {
        System.out.println("Multiply :::" + (a * b));
    }

    private void Div(int a, int b) {
        System.out.println("Division :::" + (a / b));
    }

}

Mulithreading Output:
Multithreading
Sub :::800
Division :::5
Add :::1200
Multiply :::200000
Calender - Time in milliseconds :138 415 868 0821

Here single thread executed at 138 415 866 7863 milliseconds and multithreading executed at this 138 415 868 0821 milliseconds. Then what is the real purpose of multithreading ?

informatik01
  • 16,038
  • 10
  • 74
  • 104
Naveen
  • 367
  • 2
  • 4
  • 11
  • "Then what is the real purpose of multithreading?" - there are two purposes: 1. Avoid the blocking of a short job by a long job (for example, in Swing applications there are at least two threads, one that figures out what to paint on the screen and the other which reacts to button clicking; if the thread reacting to button clicks would also paint on the screen, the buttons would not react, or react slowly, to you clicking them) 2.When there are multiple "processing units"(multicore/multiprocessor systems), JVM might dispatch different threads to different units, **perhaps** speeding up things. – John Donn Nov 15 '16 at 11:26
  • more details : http://softwareengineering.stackexchange.com/questions/97615/what-can-multiple-threads-do-that-a-single-thread-cannot – TooCool Feb 16 '17 at 21:09
  • you run multithreading one after single thread one - **that** info flows from timestamps info you outputted, not duration of runs. Some answers noted that. – Alex Martian Nov 18 '19 at 16:15

5 Answers5

39

The processing that you are doing is trivial, so the overhead of creating threads is more expensive.

If you had expensive operations which could be done in parallel then multi threads make sense.

Scary Wombat
  • 44,617
  • 6
  • 35
  • 64
  • 1
    "If you had expensive operations which could be done in parallel then multi threads make sense." thanks, thats all, what I needed to know – Mike Herasimov Jun 05 '15 at 10:57
  • 1
    @Scary Wombat: Can you define "expensive operations"? Do you mean multiplication, addition etc. with larger numbers? – cpx Nov 03 '19 at 13:19
  • expensive operations would involve stuff like intensive database searches/updates, I/O, or other operations that takes a lot of CPU - e.g. number crunching for analytics. Simple mathematics would not usually be a contender . – Scary Wombat Nov 05 '19 at 00:14
8

First: Because the overhead of creating threads more, than the useful work performed by them.If you run more hard work in threads, it will make it faster than one thread.Trivial code must be runned in one thread.

Second: For creation micro-benchmark you should use JMH

Sergey Morozov
  • 4,528
  • 3
  • 25
  • 39
6

1,384,158,667,863 milliseconds are about 44 years. So you are telling us that you waited 44 years on the result of this operation? Or could there be something wrong with the way you are measuring the speed of the execution?

To measure the difference between two times you need at least two times, while you only get the current date at the end of your program, which isn't even close to accurate.

Simple time measuring class:

public class StopWatch {
  private long startTime = -1;

  public void start() {
    this.startTime = System.nanoTime();
  }

  public long timeNanos() {
    return System.nanoTime() - this.startTime;
  }

  public double timeMillis() {
    return this.timeNanos() / 1000000.0;
  }
}

Use this Stopwatch to measure the time for execution (like you would use a stopwatch), then do it 3 times and realize that each time you get entirely different results. This is because measuring exact execution time is not trivial at all. The OS constantly interrupts the execution of your program with other tasks and seemingly easy commands can have a whole chain of background commands that need to be run.

All you can do is to approximate the time it takes by running that task like a million times and then take the average.

TwoThe
  • 13,879
  • 6
  • 30
  • 54
4

First of all, your time in miliseconds is just the timestamp. You need the difference in miliseconds between before and after the call in order to measure the elapsed time. I guess that you ran the single-threaded application first. If you try running the multi-threaded application first, you will notice that it has a lower "time in milliseconds"-value.

Second. Creating and managing threads has an overhead, which is far higher than the running time of the very simple arithmetic operations you perform. If you try to iterate the operations a few million times, you may see a performance gain by executing the operations in parallel.

Peter
  • 199
  • 4
2

If you consider one processor machine. All the threads run on a single processor. let's suppose that your program (jvm) has 0.2 secs execution time on the processor every second. If you execute on a single thread, the 0.2 seconds will be dedicated only to this main thread. If you execute it on 4 threads for example the 0.2 seconds you will not have 0.05 + 0.05 + 0.05 + 0.05. You will need to add an extra time to synchronize, resume and dispose threads. If we suppose that this operation takes 0.001 seconds for every context switching. You will get 0.004 seconds of execution time lost every second provided that a thread executes once in a second. In real life thread context switching is made many times every second and it's unpredictable. Now things are changing as there are multicore machines and threads can execute at the same time on different cores.

Please see this link for more information: Does Java have support for multicore processors/parallel processing?

Community
  • 1
  • 1
Houcem Berrayana
  • 3,052
  • 22
  • 40