1

我可以问一个菜鸟 Java 问题吗?

我正在从网上下载一些文件。此方法下载(网址位置)被多次调用。

public static void download(final String url) {
    Thread t = new Thread("download") {
        @Override
        public void run() {
            try {
                synchronized (object) {
                    // download & save
                }
            } catch(Exception e) {}
        }
    };
    t.start();
}

我添加了“同步”,以便一个接一个地进行下载。(不会同时发生多个下载)。
我猜即使 download() 被多次调用,同步也会阻塞其他线程,直到第一个线程完成。

上面的代码会起作用吗?还是我必须实施队列?并一对一出队?
同步可以阻塞“足够”的线程吗?(30?50?)还是有限制?

4

3 回答 3

3

这是如何做到的:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class QueueDownloader {
    private final ExecutorService executor = Executors.newSingleThreadExecutor();
    public void download(final String url) {
        executor.execute(new Runnable() {
            @Override
            public void run() {
                // download & save
            }
        });
    }
}

这将在单个后台线程上排队所有可运行文件(即下载)。

于 2013-04-05T09:52:38.960 回答
1

上面的代码会起作用吗?

是的,只要object在所有线程中引用同一个对象,同步块中的代码一次只会被一个线程执行。

[...] 还是我必须实施队列?并一对一出队?

一般来说,我建议您尽可能使用高级构造(例如来自 java.util.concurrent 包)。例如,您可以考虑为这些类型的事情使用执行器服务。

[...] 可以同步阻塞“足够”的线程吗?(30?50?)还是有限制?

不,没有限制。至少不接近 30 或 50 :-)

于 2012-07-23T20:04:46.810 回答
0

如果可以避免创建额外的线程,通常应该这样做。据我了解,您永远不希望两个工作项(下载)并行,因此从性能角度来看,最好的想法是使用由单个工作线程轮询的并发队列实现。

于 2012-07-23T20:24:57.200 回答