3

ディレクトリから複数のファイルを読み取り、ファイルごとに個別のスレッドを作成しようとしています。ループを繰り返している間、匿名の内部クラスは非最終変数を使用できません。

私の質問は、ループ内に複数のスレッドを作成する方法です。(ファイルごとにスレッドを手動で作成する必要があり、executor サービスなどを使用できません)

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 の各要素に変化しています。

xfor-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 に答える