I have a question about the following example. We have a main class which has to download many files from web server and DownloadTask who does the job. There is an object saveTo in Main.java who is overwriten every loop. This object is in that loop passed to DownloadTask as reference in constructor. The DownloadTask takes this object and does some work with it.
Does object
saveTocan be overwritten in for loop in main method before is can be processed byDownloadTask?1.1 Why can / why can not. How does object creation in loop works?
Does it make a difference if this:
...
for (File fileToDownload: filesToDownload ) {
File saveTo = new File("C:\\temp\\"+fileToDownload.getName());
...
would change into this:
...
File saveTo;
for (File fileToDownload: filesToDownload ) {
saveTo = new File("C:\\temp\\"+fileToDownload.getName());
...
Main.java:
public static void main(String[] args) {
ArrayList<File> filesToDownload = new ArrayList<>();
filesToDownload.add(new File("File1"));
filesToDownload.add(new File("File2"));
filesToDownload.add(new File("File3"));
...
filesToDownload.add(new File("File100"));
ExecutorService pool = Executors.newFixedThreadPool(2);
CompletionService<Boolean> completionService = new ExecutorCompletionService<>(pool);
ArrayList<Future<Boolean>> futures = new ArrayList<>();
for (File fileToDownload: filesToDownload ) {
File saveTo = new File("C:\\temp\\"+fileToDownload.getName());
Future<Boolean> f = completionService.submit(new DownloadTask(new URL("http://1.1.1.1/" + fileToDownload.getName()), saveTo));
futures.add(f);
}
for (int tasks=0;tasks<futures.size();tasks++) {
completionService.take();
}
}
And this is DownloadTask.java:
public class DownloadTask implements Callable<Boolean> {
private URL fileURL;
private File saveTo;
public DownloadTask(URL fileURL, File saveTo) {
this.fileURL = fileURL;
this.saveTo = saveTo;
}
private void downloadFile(URL fileURL, File saveTo) throws IOException {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
ReadableByteChannel readableByteChannel = Channels.newChannel(fileURL.openStream());
FileOutputStream fileOutputStream = new FileOutputStream(saveTo);
fileOutputStream.getChannel().transferFrom(readableByteChannel, 0, Long.MAX_VALUE);
fileOutputStream.close();
readableByteChannel.close();
}
@Override
public Boolean call() throws IOException {
downloadFile(fileURL, saveTo);
return true;
}
}
Thank you!