gpt4 book ai didi

Java多线程示例-对象是否共享

转载 作者:行者123 更新时间:2023-12-01 19:28:57 25 4
gpt4 key购买 nike

我对以下示例有疑问。我们有一个主类,它必须从 Web 服务器下载许多文件,而 DownloadTask 则负责完成这项工作。 Main.java 中有一个对象 saveTo,每次循环都会覆盖该对象。该对象在该循环中作为构造函数中的引用传递给 DownloadTaskDownloadTask 获取此对象并对其进行一些操作。

  1. DownloadTask处理对象之前,是否可以在main方法的for循环中覆盖saveTo对象?

    1.1 为什么可以/为什么不可以。循环中的对象创建是如何工作的?

  2. 如果这样的话会有什么不同吗:

...
for (File fileToDownload: filesToDownload ) {
File saveTo = new File("C:\\temp\\"+fileToDownload.getName());
...

会变成这样:

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

这是 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;
}
}

谢谢!

最佳答案

How does object creation in loop works?

它的工作方式与其他地方的工作方式完全相同。表达式 new File(...) 的每次求值导致 File 的新实例要从堆分配的类,它会导致使用 ... 调用构造函数。参数,它返回对新 File 的引用实例。

您的代码示例创建了一个新的 File循环的每次迭代上的实例,并将对其的引用存储在 saveTo 中局部变量,覆盖 saveTo 的先前值。分配给saveTo对新的 File 没有任何影响吗?实例,它不会File 有任何影响saveTo 的实例之前提到过。

唯一的地方saveTo使用的是下一行:

...f = completionService.submit(new DownloadTask(..., saveTo));

所以,赋值给 saveTo 的唯一效果是确定哪个File实例将提供给每个新的 DownloadTask您的程序创建的。

Does it make a difference if [the declaration of saveTo is moved out of the loop?]

它不会对程序的运行方式产生任何影响。无论哪种情况,编译器都会发出相同的代码。不过,这可能会影响其他程序员阅读您的代码的容易程度。当有人看到 saveTofor 内声明循环体,那么他们就不需要浪费任何时间来查看它可能在哪里使用。如果您在循环内声明它,那么 Java 将不允许您在循环外使用它。

关于Java多线程示例-对象是否共享,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60396511/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com