【问题标题】:Why isn't this multithreaded code faster?为什么这个多线程代码不更快?
【发布时间】:2015-08-17 04:21:40
【问题描述】:

这是我的 java 代码。之前,它依次调用BatchGenerateResult,这是一个漫长的过程,但我想尝试一些多线程并让它们中的每一个同时运行。但是,当我测试它时,新时间与旧时间相同。我预计新的时间会更快。有谁知道怎么回事?

public class PlutoMake {

  public static String classDir;

  public static void main(String[] args) throws JSONException, IOException,
      InterruptedException {

    // determine path to the class file, I will use it as current directory
    String classDirFile = PlutoMake.class.getResource("PlutoMake.class")
        .getPath();
    classDir = classDirFile.substring(0, classDirFile.lastIndexOf("/") + 1);

    // get the input arguments
    final String logoPath;
    final String filename;
    if (args.length < 2) {
      logoPath = classDir + "tests/android.png";
      filename = "result.png";
    } else {
      logoPath = args[0];
      filename = args[1];
    }

    // make sure the logo image exists
    File logofile = new File(logoPath);
    if (!logofile.exists() || logofile.isDirectory()) {
      System.exit(1);
    }

    // get the master.js file
    String text = readFile(classDir + "master.js");
    JSONArray files = new JSONArray(text);

    ExecutorService es = Executors.newCachedThreadPool();

    // loop through all active templates
    int len = files.length();
    for (int i = 0; i < len; i += 1) {
      final JSONObject template = files.getJSONObject(i);
      if (template.getBoolean("active")) {
        es.execute(new Runnable() {
          @Override
          public void run() {
            try {
              BatchGenerateResult(logoPath, template.getString("template"),
                  template.getString("mapping"),
                  template.getString("metadata"), template.getString("result")
                      + filename, template.getString("filter"),
                  template.getString("mask"), template.getInt("x"),
                  template.getInt("y"), template.getInt("w"),
                  template.getInt("h"));
            } catch (IOException | JSONException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
            }
          }
        });
      }
    }

    es.shutdown();
    boolean finshed = es.awaitTermination(2, TimeUnit.MINUTES);
  }

  private static void BatchGenerateResult(String logoPath, String templatePath,
      String mappingPath, String metadataPath, String resultPath,
      String filter, String maskPath, int x, int y, int w, int h)
      throws IOException, JSONException {
    ColorFilter filterobj = null;
    if (filter.equals("none")) {
      filterobj = new NoFilter();
    } else if (filter.equals("darken")) {
      filterobj = new Darken();
    } else if (filter.equals("vividlight")) {
      filterobj = new VividLight();
    } else {
      System.exit(1);
    }

    String text = readFile(classDir + metadataPath);
    JSONObject metadata = new JSONObject(text);

    Map<Point, Point> mapping = MyJSON.ReadMapping(classDir + mappingPath);

    BufferedImage warpedimage = Exporter.GenerateWarpedLogo(logoPath, maskPath,
        mapping, metadata.getInt("width"), metadata.getInt("height"));
    // ImageIO.write(warpedimage, "png", new FileOutputStream(classDir +
    // "warpedlogo.png"));

    Exporter.StampLogo(templatePath, resultPath, x, y, w, h, warpedimage,
        filterobj);

    warpedimage.flush();
  }

  private static String readFile(String path) throws IOException {
    File file = new File(path);
    FileInputStream fis = new FileInputStream(file);
    byte[] data = new byte[(int) file.length()];
    fis.read(data);
    fis.close();
    String text = new String(data, "UTF-8");
    return text;
  }
}

【问题讨论】:

  • 您的机器有多少个 CPU 内核?试试System.out.println(Runtime.getRuntime().availableProcessors()); 打印什么?
  • 2 cpu(4 线程,intel i3 generation 1)
  • @sneaky,试试Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); 并立即检查性能。还有你有多少文件? len 变量的值是多少?
  • 可能你在 MyJSON、Exporter 类中有同步方法?

标签: java multithreading performance


【解决方案1】:

看起来,出于所有实际目的,以下代码应该是唯一可以通过使用多线程来提高性能的代码。

BufferedImage warpedimage = Exporter.GenerateWarpedLogo(logoPath, maskPath,
    mapping, metadata.getInt("width"), metadata.getInt("height"));
// ImageIO.write(warpedimage, "png", new FileOutputStream(classDir +
// "warpedlogo.png"));

Exporter.StampLogo(templatePath, resultPath, x, y, w, h, warpedimage,
    filterobj);

其余的主要 IO - 我怀疑你可以在那里实现多少性能改进。

做一个配置文件并检查每个方法的执行时间。取决于你应该能够理解。

【讨论】:

    【解决方案2】:

    您好,很抱歉无法添加到刚刚加入的评论部分..

    建议首先使用虚拟方法检查它是否在您的最后工作,然后添加您的业务逻辑...... 如果示例有效,那么您可能需要检查您的“模板”类 这是示例.. 检查时间戳

     package example;
    
        import java.util.concurrent.ExecutorService;
        import java.util.concurrent.Executors;
    
        public class ExecutorStaticExample {
    
    
            public static void main(String[] args){
                ExecutorService  ex = Executors.newCachedThreadPool();
                for (int i=0;i<10;i++){
                        ex.execute(new Runnable(){
    
                            @Override
                            public void run() {
                                helloStatic();
                                System.out.println(System.currentTimeMillis());
    
                            }
    
                        });
                }
            }
    
            static void helloStatic(){
                System.out.println("hello form static");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
    
        }
    

    【讨论】:

    • 此示例与此代码无关。如果您回答了一些您确实知道如何回答的问题,您将能够对此问题发表评论。
    • @durron.. 是不是先检查基本功能,再添加业务逻辑?
    • 不过,这并不能回答问题。调试提示不是答案。
    猜你喜欢
    • 2014-11-10
    • 1970-01-01
    • 2021-10-11
    • 2012-06-29
    • 1970-01-01
    • 1970-01-01
    • 2012-01-16
    • 1970-01-01
    • 2017-04-16
    相关资源
    最近更新 更多