对于SwingWorker中的循环

时间:2014-08-24 09:00:22

标签: java swingworker

只是想明确了解在SwingWorker doInbackground方法中使用for循环。

例如,我有一个存储在FilesFile[] Files = ...)中的文件列表。

scanFiles = new SwingWorker<Object, Object>(){ 
      public Object doInBackground(){
          for( File f : Files ){
             // process file f
          }
      }
}
....
scanFiles.execute();

在上面,可以在doInBackGround()方法中使用for循环来浏览文件列表,还是最好将for loop移到doInBackground()之外方法,如下所示:

for ( File f: Files ){
   processFile(f);
}

private void processFile(File f){
    scanFiles = new SwingWorker<Object, Object>(){ 
     public Object doInBackground(){
           // do something with f
     }
    }
}

以上是骨架代码,而不是实际工作代码。仅仅是为了说明我想要做什么。也就是说,我不希望我的程序逐个扫描文件。我想做一些像文件的并行处理...... 感谢

2 个答案:

答案 0 :(得分:1)

如果你想平行处理文件,你必须产生一些线程工作者,所以第二个样本应该是你的选择。您可以使用以下方法通知UI或程序的其他组件有关处理文件的进度:protected void process(List<V> chunks)protected final void publish(V... chunks)

private void processFile(File f){
    scanFiles = new SwingWorker<Object, Object>(){ 
     public Object doInBackground(){
           publish(V... chunks)
     }
    }
}

protected void process(List<V> chunks) {
  //do something with intermediate data, for example show progress in the ui
}

答案 1 :(得分:1)

正如一些评论中所提到的:适当的解决方案在很大程度上取决于您要处理的文件数量,以及processFile实际所做的

你的方法之间的主要区别是(正如MadProgrammer已经说过的那样)

  • 第一个创建一个后台线程来处理所有文件
  • 第二个创建许多后台线程,每个线程处理一个文件

其中任何一种方法都不合适的边界情况类似:

  • 许多文件时,第一个可能会更好,而processFile简单操作
  • 少数文件且processFile复杂操作时,第二个可能会更好

但这只是一个粗略的分类,哪一个是“最佳”方法仍然取决于其他因素。

但是,我想提出另一个解决方案,它允许您在两个极端之间灵活地“转换”:您可以创建包含List个对象的File,并拆分此列表进入指定数量的“块”,让它们由SwingWorker处理。

在此处草拟,以显示基本想法:您创建一个方法来处理带有SwingWorker的文件列表:

private void processFiles(final List<File> files) {
    SwingWorker<Object, Object> scanFiles = new SwingWorker<Object, Object>(){ 
        @Override
        public Object doInBackground(){
            // do something with files
        }
    }
}

然后,在呼叫站点,您可以执行以下操作:

// Obtain the list of files to process
File files[] = ...
List<File> fileList = Arrays.asList(files);

// Define the number of workers that should be used
int numWorkers = 10;

// Compute how many files each worker will process
int chunkSize = (int)Math.ceil((double)fileList.size() / numWorkers);

for (int i=0; i<numWorkers; i++) {

    // Compute the part of the "fileList" that the worker will process
    int minIndex = i * chunkSize;
    int maxIndex = i * chunkSize + chunkSize;
    maxIndex = Math.min(maxIndex, fileList.size());
    List<File> chunk = fileList.sublist(minIndex, maxIndex);

    // Start the worker
    processFiles(chunk);
}

(这只是一个草图。可能会有一些索引麻烦。如果需要,我可以发布一个更详细的版本。到现在为止,它只显示了基本的想法)

然后,您可以定义要使用的工作线程数(甚至可能取决于Runtime.getRuntime().availableProcessors()的数量。)