3

我试图从一个目录中读取多个文件并为每个文件创建一个单独的线程。在迭代循环时,匿名内部类不能使用非最终变量。

我的问题是如何在循环中创建多个线程。(我需要为每个文件手动创建线程,不能使用执行器服务或其他东西)

class de
{

    void commit(File x){

       int sum =0;
       try{
           FileInputStream fin = new FileInputStream(x);
           byte[]b= new byte[5000];
           fin.read(b);
           for (byte digit:b){
               sum=digit+sum;
           }
           System.out.println(sum);
       }
       catch(Exception e){}
    }
    public static void main (String args[]){    
        File f = new File("C:\\Users\\Sanjana\\workspace\\IO\\Numbers");
        File []store = f.listFiles( new FilenameFilter(){
            public boolean accept(File f, String name){
                return name.endsWith("txt");
            }
        });

       for (File x: store){   
           Thread t = new Thread(){
               public void run (){
               //new de().commit(x); /**/Error here non final variable x**
               }
           };
       }
    }    
}
4

1 回答 1

4

改变

for (File x: store)

for (final File x: store)

编辑你的状态:

它的工作但最终变量是恒定的,这里 x 正在更改为 store.howz 的每个工作元素

x是 for-each 循环的参数,可以根据 for-each 循环的定义声明为 final。每次循环循环,就好像 x 被重新创建。


根据增强 for 循环的JLS 14.14.2部分:

增强的 for 语句等效于以下形式的基本 for 语句:

for (I #i = Expression.iterator(); #i.hasNext(); ) {
    VariableModifiersopt TargetType Identifier =
        (TargetType) #i.next();
    Statement
}

所以这告诉我 final 会像这样适合:

for (I #i = Expression.iterator(); #i.hasNext(); ) {
    final VariableModifiersopt TargetType Identifier =
        (TargetType) #i.next();
    Statement
}

所以这x实际上是上面的标识符,实际上是在循环的每次迭代中重新声明的。

在您的代码中,我认为它相当于:

  for (Iterator<File> iterator = Arrays.asList(scores).iterator(); iterator.hasNext();) {
     final File file = iterator.next();
     new Thread(new Runnable() {
        public void run() {
           new de().commit(file);
        }
     }).start();  
  }

编辑 2
请注意,您对 Thread 的使用可以得到改进,您应该养成使用 Runnable 的习惯:

   for (final File x: store){   
       new Thread(new Runnable() {

         @Override
         public void run() {
           new de().commit(x);  // "de" should be "De" since it is a class
         }
       }).start();
    }
于 2013-08-24T17:46:44.260 回答