2013-08-24 8 views
3

J'essaie de lire les fichiers multiples à partir d'un répertoire et de créer un thread séparé pour chaque fichier. Pendant l'itération de la boucle, la classe interne anonyme ne peut pas utiliser de variables non finales.Multithreading inside pour la boucle

Ma question est de savoir comment créer plusieurs threads dans une boucle. (Je dois créer manuellement threads pour chaque fichier, le service dévers exécuteur utilisation ou autre chose)

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** 
       } 
      }; 
     } 
    }  
} 
+0

Merci d'avoir modifié votre code affiché! –

+1

Etes-vous sûr de lire ces fichiers à partir de plusieurs threads permettra d'améliorer les performances des applications? S'il vous plaît gardez à l'esprit que votre disque dur ne peut pas avoir sa tête de lecture à des positions différentes. – oddparity

Répondre

4

changement

for (File x: store) 

à

for (final File x: store) 

Modifier vous déclarez:

Son travail, mais les variables finales sont constantes, ici x est changeant à chaque élément de store.howz que le travail

x est un paramètre de la boucle for-each et peut être déclaré final selon la définition de for-each loop. Chaque fois que la boucle boucle, c'est comme si x était créé à nouveau.


par la section JLS 14.14.2 sur l'amélioration de boucle:

La version améliorée de déclaration équivaut à une base pour la déclaration de la forme:

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

Donc, ce dit moi que la finale s'insérerait comme ça:

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

Donc le x est vraiment l'identifiant ci-dessus et est en réalité re-déclaré à chaque itération de la boucle.

Dans votre code, je pense qu'il est équivalent à:

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

Edit 2
Notez que votre utilisation de fil peut être améliorée, que vous devriez prendre l'habitude d'utiliser un 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(); 
    } 
+0

Ses variables de travail mais définitives sont constantes, ici x change à chaque élément de store.howz cela fonctionne – Sanjana

+0

@Sanjana: s'il vous plaît voir ** Edit 2 ** pour répondre. –