亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

這是使用執行器服務實現多線程的正確方法嗎?

這是使用執行器服務實現多線程的正確方法嗎?

郎朗坤 2022-06-08 16:25:51
我正在嘗試使用執行程序服務來教自己使用多線程,并且想知道在下面實現我的代碼的最佳實踐是什么-我正在閱讀文本文件目錄并檢查字符/單詞-如果我所做的只是通過文件列表對每個線程進行處理,我也很困惑是否正在使用多個線程。是否同時處理多個文件?主班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;    }
查看完整描述

1 回答

?
慕田峪4524236

TA貢獻1875條經驗 獲得超5個贊

不。這不是正確的方法。您提交一個進程,然后通過調用get()未來,您阻塞并等待它完成,因此它實際上是一個同步處理。有兩種方法可以進行并行、異步處理:


1)invokeAll()


這是更簡單的方法,但它需要您提前創建所有流程實例,因此這取決于您要執行多少并行任務(如果您有數百萬個,您可能會達到內存限制)。創建流程后,您可以立即將它們提交給執行者。它將并行執行所有任務(根據線程池大?。┎⒃谒腥蝿胀瓿珊蠓祷亍?/p>


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

               }

          }

      }


查看完整回答
反對 回復 2022-06-08
  • 1 回答
  • 0 關注
  • 96 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號