【问题标题】:Java/Android: Synchronized vs Queue implementationJava/Android:同步与队列实现
【发布时间】:2012-07-23 20:02:50
【问题描述】:

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

我正在从网上下载一些文件。这个方法download(url location)被多次调用。

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?)还是有限制?

【问题讨论】:

    标签: java android synchronization queue synchronized


    【解决方案1】:

    这是怎么做的:

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

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

    【讨论】:

      【解决方案2】:

      上面的代码可以工作吗?

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

      [...] 还是我必须实现队列?并逐个出队?

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

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

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

      【讨论】:

        【解决方案3】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-01-23
          • 2011-05-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多