猿问

这是使用执行器服务实现多线程的正确方法吗?

我正在尝试使用执行程序服务来教自己使用多线程,并且想知道在下面实现我的代码的最佳实践是什么-我正在阅读文本文件目录并检查字符/单词-


如果我所做的只是通过文件列表对每个线程进行处理,我也很困惑是否正在使用多个线程。是否同时处理多个文件?


主班


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;

    }



郎朗坤
浏览 123回答 1
1回答

慕田峪4524236

不。这不是正确的方法。您提交一个进程,然后通过调用get()未来,您阻塞并等待它完成,因此它实际上是一个同步处理。有两种方法可以进行并行、异步处理:1)invokeAll()这是更简单的方法,但它需要您提前创建所有流程实例,因此这取决于您要执行多少并行任务(如果您有数百万个,您可能会达到内存限制)。创建流程后,您可以立即将它们提交给执行者。它将并行执行所有任务(根据线程池大小)并在所有任务完成后返回。&nbsp; &nbsp; &nbsp; List<Callable<FileReadings>> tasks = new Arraylist<>();&nbsp; &nbsp; &nbsp; for (File file : x.getFileList()) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;tasks.add(new Process(file));&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; // submit all processes at once. they will be processed in parallel&nbsp;&nbsp; &nbsp; &nbsp; // this call blocks until all tasks are finished&nbsp; &nbsp; &nbsp; List<Future<FileReadings>> responses = executor.invokeAll(tasks);&nbsp; &nbsp; &nbsp; // at this point all processes finished. all get() will return immediately&nbsp; &nbsp; &nbsp; for (Future<FileReadings> response : responses) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;x.totalCharacterCount += response.get().characterCount;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;x.totalLineCount += response.get().lineCount;&nbsp; &nbsp; &nbsp; }2)submit()当您创建一个进程并立即提交它时,此解决方案更具可扩展性,因此内存需求是恒定的(不包括执行程序)。但是,您需要自己管理响应:&nbsp; &nbsp; &nbsp; List<Future<FileReadings>> responses = new ArrayList<>();&nbsp; &nbsp; &nbsp; for (File file : x.getFileList()) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;responses.add(executor.submit(new Process(file)));&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; // at this point all processes submitted but not finished.&nbsp; &nbsp; &nbsp; // need to check which is finished at intervarls&nbsp; &nbsp; &nbsp; while (responses.isEmpty() == false) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Thread.sleep(1000);&nbsp; // allow some processing time for tasks&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // ListIterator allows removing items&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ListIterator<Future<FileReadings>> itr = responses.listIterator();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while (itr.hasNext()) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Future<FileReadings> response = itr.next();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// if task is complete, get it and remove from list&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (response.isDone()) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;x.totalCharacterCount += response.get().characterCount;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;x.totalLineCount += response.get().lineCount;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;itr.remove();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; }
随时随地看视频慕课网APP

相关分类

Java
我要回答