Faster multiple threading vs single threading

I'm implementing an online store where customers drop in an order and my program generates a summary of who the client is and what items they bought.

public class Summarizer{
private TreeSet<Order> allOrders = new TreeSet<Order>(new OrderComparator());

public void oneThreadProcessing(){
    Thread t1;
    for(Order order: allOrders){
        t1 = new Thread(order);
        t1.start();
        try {
            t1.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public void multipleThreadProcessing(){
    Thread[] threads = new Thread[allOrders.size()];
    int i = 0;
    for(Order order: allOrders){
        threads[i] = new Thread(order);
        threads[i].start();
        i++;
    }
    for(Thread t: threads){
        try {
            t.join();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }           
    }
}

public static void main (String[] args) {
    Summarizer s = new Summarizer();
    long startTime = System.currentTimeMillis();
    s.oneThreadProcessing();
    long endTime = System.currentTimeMillis();
    System.out.println("Processing time (msec): " + (endTime - startTime));

    System.out.println("-------------Multiple Thread-------------------------------");
    long startTime1 = System.currentTimeMillis();
    s.multipleThreadProcessing();
    long endTime1 = System.currentTimeMillis();
    System.out.println("Processing time (msec): " + (endTime1 - startTime1));

This is my Order class:

   public class Order implements Runnable, Comparable<Order> {
            private int clientId;

        @Override
        public void run() {
        /*
        Print out summary in the form:
        Client id: 1001
        Item: Shoes, Quantity: 2, Cost per item: $30.00, Total Cost: $60.00
        Item: Bag, Quantity: 1, Cost per item: $15.00, Total Cost: $15.00
        Total: $75.00
        /*

    }
}

Assuming I fill in this TreeSet with all the orders in a particular day sorted by the client ID numbers, I wanna generate the summaries of all these orders using only one thread and then multiple threads and compare the performance. The requirement is to have the multiple threaded performance be better and I would assume it would be but every time I run my main method. The multiple threading is actually almost always slower. Am I doing something wrong? I know one can never be certain that the multiple threading program will be faster but since I'm not dealing with any locking as of yet, shouldn't my program be faster in the multipleThreadedProcessing()? Is there any way to ensure it is faster then?

Answers


Multi threading is not a magic powder one sprinkes onto code to make it run faster. It requires careful thought about what you're doing.

Let's analyze the multi threaded code you've written.

You have many Orders (How many btw? dozens? hundreds? thousands? millions?) and when executed, each order prints itself to the screen. That means that you're spawning a possibly enormous number of threads, just so each of them would spend most of its time waiting for System.out to become available (since it would be occupied by other threads). Each thread requires OS and JVM involvement, plus it requires CPU time, and memory resources; so why should such a multi threaded approach run faster than a single thread? A single thread requires no additional memory, and no additional context switching, and doesn't have to wait for System.out. So naturally it would be faster.

To get the multi threaded version to work faster, you need to think of a way to distribute the work between threads without creating unnecessary contention over resources. For one, you probably don't need more than one thread performing the I/O task of writing to the screen. Multiple threads writing to System.out would just block each other. If you have several IO devices you need to write to, then create one or more threads for each (depending on the nature of the device). Computational tasks can sometimes be executed quicker in parallel, but:

A) You don't need more threads doing computation work than the number of cores your CPU has. If you have too many CPU-bound threads, they'd just waste time context switching.

B) You need to reason through your parallel processing, and plan it thoroughly. Give each thread a chunk of the computational tasks that need to be done, then combine the results of each of them.


Need Your Help

including two functions in a javascript keypress

javascript

As a standard feature I keep a "don't allow returns" on form text fields using:

Why doesn't the following query work with double LIKE clause?

java google-app-engine jpa persistence google-cloud-datastore

I'm using GAE's datastore and JPA persistence framework to store my entities. Though when attempting to retreive some specific entities I run into the problem mentioned below.