Reputation: 467
I am trying to read the multiple files from a directory and create a separate thread for every file.While iterating the loop, the anonymous inner class cannot use non final variables.
My question is how to create multiple threads inside a loop.(I am required to manually create threads for each file, cant use executor service or something else)
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**
}
};
}
}
}
Upvotes: 3
Views: 3071
Reputation: 285450
Change
for (File x: store)
to
for (final File x: store)
Edit you state:
Its working but final variables are constant, here x is changing to each element of store.howz that working
x
is a parameter of the for-each loop and can be declared final as per the definition of for-each loop. Each time the loop loops, it's as if x is created anew.
Per the JLS 14.14.2 section on the enhanced for loop:
The enhanced for statement is equivalent to a basic for statement of the form:
for (I #i = Expression.iterator(); #i.hasNext(); ) {
VariableModifiersopt TargetType Identifier =
(TargetType) #i.next();
Statement
}
So this tells me that final would fit in like so:
for (I #i = Expression.iterator(); #i.hasNext(); ) {
final VariableModifiersopt TargetType Identifier =
(TargetType) #i.next();
Statement
}
So the x
is really the Identifier above and is in actuality re-declared with each iteration of the loop.
In your code, I'm thinking that it's equivalent to:
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
Note that your use of Thread can be improved, that you should get in the habit of using a 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();
}
Upvotes: 4