【问题标题】:One extra thread drastically improves performance一个额外的线程极大地提高了性能
【发布时间】:2017-03-21 17:46:12
【问题描述】:

有几个问题,例如herehere,询问为什么额外的线程会降低性能。我明白了。

我有一个有点相反的问题:一个额外的线程如何才能将性能提高一倍? 10个甚至20个?

示例代码:

           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();
        }

    }
}
  • 第一个没有线程的应用程序需要大约。 40 毫秒
  • 第二个版本,只创建一个额外的new Thread() 需要 2 毫秒。

所以我的问题是:如此大幅度的改进背后的原因是什么?

【问题讨论】:

  • 您确定要等待线程完成吗?可以出示一下代码吗?
  • 你考虑过磁盘缓存吗?
  • 你是如何实现第二个版本的?如果没有看到这两个代码,很难判断会发生什么。也许你先运行单线程,当第二个运行时,文件已经在系统的文件系统缓存中?
  • 拙劣的基准测试会给出各种奇怪的结果。
  • @Andrey,但是在您的完整代码中,您只是启动线程,您没有测量在 doAdd() 中执行实际工作所需的时间。或者更确切地说,您无需等待任何线程完成,您只需启动它们,然后打印出启动线程所需的时间。

标签: java multithreading concurrency


【解决方案1】:

当您调用 thread.start() 时,您的代码不会等待线程完成其工作后再继续。 start() 是所谓的“非阻塞”或“异步”方法。

为了准确计时,您需要在测量所用时间之前以某种方式等待线程完成。一种方法是跟踪您创建的所有线程,然后在将它们全部关闭后,在最后为它们中的每一个调用“thread.join()”。 Thread.join() 将阻塞(等待)线程完成后再继续。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-24
    • 2017-11-04
    • 1970-01-01
    • 1970-01-01
    • 2020-11-27
    相关资源
    最近更新 更多