Can I ask a rookie Java question?
我可以问一个新手Java问题吗?
I am downloading some files from the web. This method download(url location) is called multiple times.
我正在从网上下载一些文件。此方法下载(url位置)被多次调用。
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();
}
I added "synchronized" so that downloads happens one-by-one. (not multiple downloads occur at the same time).
I am guessing even though download() is called multiple times, synchronized will block other threads until the first thread is finished.
我添加了“synchronized”,以便逐个下载。 (不会同时发生多次下载)。我猜即使download()被多次调用,synchronized会阻塞其他线程,直到第一个线程完成。
Will above code work? or do I have to implement Queue? and dequeue one-by-one?
Can synchronized block "enough" threads? (30? 50?) or does it have limits?
以上代码会起作用吗?还是我必须实施队列?然后一个一个地出列?可以同步阻止“足够”的线程吗? (30?50?)或是否有限制?
3 个解决方案
#1
3
Will above code work?
以上代码会起作用吗?
Yes, as long as object
refers to the same object in all threads, the code in the synchronized block will only be executed by one thread at a time.
是的,只要object引用所有线程中的同一个对象,synchronized块中的代码一次只能由一个线程执行。
[...] or do I have to implement Queue? and dequeue one-by-one?
[...]或者我必须实施队列?然后一个一个地出列?
Generally speaking I would recommend you to use as high-level constructs as possible (for instance from the java.util.concurrent package). You may for instance consider using an executor service for these types of things.
一般来说,我建议您尽可能使用高级构造(例如来自java.util.concurrent包)。例如,您可以考虑对这些类型的事物使用执行程序服务。
[...] Can synchronized block "enough" threads? (30? 50?) or does it have limits?
[...]可以同步阻止“足够”的线程吗? (30?50?)或是否有限制?
No, no limits. At least not near 30 or 50 :-)
不,没有限制。至少不接近30或50 :-)
#2
3
Here's how to do it:
这是怎么做的:
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
}
});
}
}
This will queue all runnables (i.e. downloads) on a single background-thread.
这将在单个后台线程上排队所有可运行的(即下载)。
#3
0
If you can avoid creating additional threads, you should generally do so. As I understood it, you never want two work items (downloads) in parallel, so the best idea, performance-wise, is using a concurrent queue implementation that is polled by a single worker thread.
如果您可以避免创建其他线程,通常应该这样做。据我所知,你从不想要并行使用两个工作项(下载),因此最好的想法是性能方面是使用由单个工作线程轮询的并发队列实现。
#1
3
Will above code work?
以上代码会起作用吗?
Yes, as long as object
refers to the same object in all threads, the code in the synchronized block will only be executed by one thread at a time.
是的,只要object引用所有线程中的同一个对象,synchronized块中的代码一次只能由一个线程执行。
[...] or do I have to implement Queue? and dequeue one-by-one?
[...]或者我必须实施队列?然后一个一个地出列?
Generally speaking I would recommend you to use as high-level constructs as possible (for instance from the java.util.concurrent package). You may for instance consider using an executor service for these types of things.
一般来说,我建议您尽可能使用高级构造(例如来自java.util.concurrent包)。例如,您可以考虑对这些类型的事物使用执行程序服务。
[...] Can synchronized block "enough" threads? (30? 50?) or does it have limits?
[...]可以同步阻止“足够”的线程吗? (30?50?)或是否有限制?
No, no limits. At least not near 30 or 50 :-)
不,没有限制。至少不接近30或50 :-)
#2
3
Here's how to do it:
这是怎么做的:
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
}
});
}
}
This will queue all runnables (i.e. downloads) on a single background-thread.
这将在单个后台线程上排队所有可运行的(即下载)。
#3
0
If you can avoid creating additional threads, you should generally do so. As I understood it, you never want two work items (downloads) in parallel, so the best idea, performance-wise, is using a concurrent queue implementation that is polled by a single worker thread.
如果您可以避免创建其他线程,通常应该这样做。据我所知,你从不想要并行使用两个工作项(下载),因此最好的想法是性能方面是使用由单个工作线程轮询的并发队列实现。