这是落实使用执行多线程服务的正确方法是什么?

问题描述 投票:-1回答:1

我试图教我使用执行服务使用多线程技术,我想知道什么是最好的做法是执行我的代码如下 - 我读的文本文件的目录和检查字/词 -

此外,我很困惑是否正在使用多个线程,如果我要做的就是为每个通过的文件列表。多个文件正在对曾在一次?

大类

public class Application {

    private long totalCharacterCount;
    private long totalLineCount;
    private final File[] fileList;
    private final static String _DIRECTORY = "src//documents";

    public Application(String directory){
        fileList = new File(directory).listFiles();
    }
    public synchronized File[] getFileList(){
        return fileList;
    }
    public static void main(String[] args) throws InterruptedException, ExecutionException {
           ExecutorService executor = Executors.newFixedThreadPool(4);

          Application x = new Application(_DIRECTORY);

          for(File file : x.getFileList()){
               Future<FileReadings> response = executor.submit(new Process(file));
               x.totalCharacterCount += response.get().characterCount;
               x.totalLineCount += response.get().lineCount;

          }
          System.out.println("Total lines in all documents: " + x.totalLineCount);
          System.out.println("Total characters in all documents: " + x.totalCharacterCount);
          executor.shutdown();
    }
}

流程类

public class Process implements Callable<FileReadings> {

    private FileReadings object;
    private File file;
    public Process(File file){
        FileReadings obj = new FileReadings();
        this.object = obj;

        this.file = file;
    }

    public void CountCharacters(File file){
        int count = 0;
        try {

            BufferedReader reader = Files.newBufferedReader(file.toPath());
            while(reader.read() != -1){
                count++;
            }
            object.characterCount = reader.read();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
            object.characterCount = count;
    }
    public void CountLines(File file){
        try {
            Stream<String> text = Files.lines(file.toPath());
            object.lineCount = text.count();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public FileReadings call() throws Exception {
        CountCharacters(this.file);
        CountLines(this.file);
        System.out.println("THERE WERE: " + object.characterCount + " CHARACTERS IN: " + file.getName());
        System.out.println("THERE WERE: " + object.lineCount + " LINES IN: " + file.getName());
        return object;
    }
}

文件进行读取类

public class FileReadings {
     long characterCount;
     long lineCount;
}

结果是:

THERE WERE: 65 CHARACTERS IN: test1.txt
THERE WERE: 10 LINES IN: test1.txt
THERE WERE: 88 CHARACTERS IN: test2.txt
THERE WERE: 21 LINES IN: test2.txt
Total lines in all documents: 31
Total characters in all documents: 153
java multithreading
1个回答
1
投票

没有。这不是正确的方法。你提交一个过程,然后通过调用get()未来,您阻止并等待它完成,如此有效它是一个同步处理。有两种方法可以做到并行,异步处理:

1)invokeAll()

这是更简单的方法,但它需要您提前创建所有的流程实例,所以这取决于你想要多少并行任务执行(如果你有百万人,你会打一个内存限制)。一旦你创建的过程中,您提交他们在一次执行程序。它会并行执行所有任务(根据线程池的大小),当所有完成后返回。

      List<Callable<FileReadings>> tasks = new Arraylist<>();
      for (File file : x.getFileList()) {
           tasks.add(new Process(file));
      }
      // submit all processes at once. they will be processed in parallel 
      // this call blocks until all tasks are finished
      List<Future<FileReadings>> responses = executor.invokeAll(tasks);
      // at this point all processes finished. all get() will return immediately
      for (Future<FileReadings> response : responses) {
           x.totalCharacterCount += response.get().characterCount;
           x.totalLineCount += response.get().lineCount;
      }

2)submit()

当你创建一个进程,并立即提交,因此内存的要求不变(不包括执行人)这种解决方案更具可扩展性。不过,你需要自己管理的对策:

      List<Future<FileReadings>> responses = new ArrayList<>();
      for (File file : x.getFileList()) {
           responses.add(executor.submit(new Process(file)));
      }
      // at this point all processes submitted but not finished.
      // need to check which is finished at intervarls
      while (responses.isEmpty() == false) {
          Thread.sleep(1000);  // allow some processing time for tasks
          // ListIterator allows removing items
          ListIterator<Future<FileReadings>> itr = responses.listIterator();
          while (itr.hasNext()) {
               Future<FileReadings> response = itr.next();
               // if task is complete, get it and remove from list
               if (response.isDone()) {
                   x.totalCharacterCount += response.get().characterCount;
                   x.totalLineCount += response.get().lineCount;
                   itr.remove();
               }
          }
      }
© www.soinside.com 2019 - 2024. All rights reserved.