Andrejs
Andrejs

Reputation: 11931

One extra thread drastically improves performance

There are several questions, like here or here, asking why extra threads decrease performance. I get those.

I have a somewhat opposite question: how can just one extra thread increase performance by a factor of e.g. 10 or even 20?

Example code:

           public class MainThreaded {

    public static void main(String[] 

        String filePath = "my\\path\\";

        String[] inFiles = {filePath+"file1.txt",filePath+"file2.txt"};
        String[] outFiles = {filePath + "file1Out.txt", filePath + "file2Out.txt"};

        long startTime = System.currentTimeMillis();

            for (int i = 0; i < inFiles.length; i++) {

                Adder adder = new Adder(inFiles[i], outFiles[i]);
//              adder.doAdd();
                Thread thread = new Thread(adder);
                thread.start();
            }

        long endTime   = System.currentTimeMillis();
        long totalTime = endTime - startTime;
        System.out.println("That took " + totalTime+ " milliseconds");


    }

}



public class MainNoThread {

    public static void main(String[] args) {


        String filePath = "my\\path\\";    
        String[] inFiles = {filePath+"file1.txt",filePath+"file2.txt"};
        String[] outFiles = {filePath + "file1Out.txt", filePath + "file2Out.txt"};

        long startTime = System.currentTimeMillis();

            for (int i = 0; i < inFiles.length; i++) {

                Adder adder = new Adder(inFiles[i], outFiles[i]);
                try {
                    adder.doAdd();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }

        long endTime   = System.currentTimeMillis();
        long totalTime = endTime - startTime;
        System.out.println("That took " + totalTime+ " milliseconds");

    }

}

public class Adder implements Runnable {

    private String inFile, outFile;

    public Adder(String inFile, String outFile){
        this.inFile = inFile;
        this.outFile = outFile;

    }

    public void doAdd() throws IOException{

        int lines = 0;

        try(BufferedReader reader = Files.newBufferedReader(Paths.get(inFile))){
            while (reader.readLine() != null) {
                lines++;
            }
            try(BufferedWriter writer = Files.newBufferedWriter(Paths.get(outFile))){
                writer.write("Total: " + lines);
            }
        }

    }

    @Override
    public void run() {

        try {
            doAdd();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

So my question: what is the reason behind such drastic improvement?

Upvotes: 0

Views: 63

Answers (1)

CAW
CAW

Reputation: 389

When you call thread.start(), your code does not wait for the thread to finish doing its work before moving on. start() is what is known as a "non-blocking" or "asynchronous" method.

In order to time this accurately, you need to somehow wait for the threads to finish before measuring the time taken. One way to do this is to keep track of all of the threads you create, and then call "thread.join()" for each of them at the end, after kicking them all off. Thread.join() will block (wait) for a thread to finish before continuing.

Upvotes: 1

Related Questions