执行器服务或守护线程哪个更适合多线程?
Executor service or daemon threads which is better for multi threads?
抱歉编辑时间过长,
我正在尝试下载 100k urls 并且我开始使用执行程序服务下载,如下所示,
ExecutorService executorService = Executors.newFixedThreadPool(100);
for (int i = 0; i < list.size(); i++) {
try {
Callable callable = new Callable() {
public List<String> call() throws Exception {
//http connection
}
};
Future future = executorService.submit(callable);
但是上面的方法一次只下载一个url..
所以我尝试创建守护进程线程(如下所示)并且此方法创建了多个下载连接(如预期的那样)..
for(int i=0; i<10; i++) {
Thread t = new Thread("loadtest " + i);
t.setDaemon(true);
t.start();
}
while(true) {
boolean flag = true;
Set<Thread> threads = Thread.getAllStackTraces().keySet();
for(Thread t : threads) {
if(t.isDaemon() && t.getName().startsWith("loadtest")) {
flag = false;
break;
}
}
if(flag)
break;
Thread.sleep(5000);
}
是否可以使用相同的方法对服务器进行负载测试?
关于如何进行负载测试的任何其他建议也将有很大帮助..
提前致谢!
守护线程是在所有其他线程完成时不阻止 JVM 退出的线程。
我相信如果您想等待主线程直到守护线程未完成,那么我建议不要使用守护线程,因为它不应该用于该用例。您可以使用 Thread#join
来等待您的主线程。
for(int i=0; i<10; i++) {
Thread t = new Thread("loadtest " + i);
t.setDaemon(true);
t.start();
t.join(); // main or parent thread will wait util the child thread finished
}
我相信在你的用例中你应该使用普通线程而不是守护进程。
我会冒险猜测你的 ExecutorService
没有工作,因为你在 Future
实例上调用 get()
它 returns 在你的循环。这个错误确实会导致你的处理被序列化,就好像你只有一个线程一样,因为另一个任务在第一个完成之前不会提交。
如果您确实需要使用 Callable
,请不要 get()
结果,直到您准备好在任务完成时无限期地阻塞——如果它们无法完成还没有提交。对于下载 URLs,最好使用 Runnable
,主线程提交 URLs 然后忘记任务;该任务可以独立完成其 URL.
的处理
如果您快速生成新任务,您可能会排队太多以至于 运行 内存不足。在这种情况下,您可以使用有界队列并直接使用 ThreadPoolExecutor
设置适当的拒绝处理程序。
负载测试不仅是关于 "hammering" 您的服务器的请求,行为良好的负载测试需要代表 真实用户 使用真实浏览器以及所有相关内容,例如:
所以我建议使用专门的 load testing tool which are capable of representing real user as close as possible and automatically taking care of aforementioned points. Also normally the load testing tools allow you to set rendezvous points 并提供大量指标和图表,以便您能够看到连接时间、网络延迟、吞吐量,将增加的负载与增加的响应相关联 time/number 错误等
抱歉编辑时间过长,
我正在尝试下载 100k urls 并且我开始使用执行程序服务下载,如下所示,
ExecutorService executorService = Executors.newFixedThreadPool(100);
for (int i = 0; i < list.size(); i++) {
try {
Callable callable = new Callable() {
public List<String> call() throws Exception {
//http connection
}
};
Future future = executorService.submit(callable);
但是上面的方法一次只下载一个url..
所以我尝试创建守护进程线程(如下所示)并且此方法创建了多个下载连接(如预期的那样)..
for(int i=0; i<10; i++) {
Thread t = new Thread("loadtest " + i);
t.setDaemon(true);
t.start();
}
while(true) {
boolean flag = true;
Set<Thread> threads = Thread.getAllStackTraces().keySet();
for(Thread t : threads) {
if(t.isDaemon() && t.getName().startsWith("loadtest")) {
flag = false;
break;
}
}
if(flag)
break;
Thread.sleep(5000);
}
是否可以使用相同的方法对服务器进行负载测试?
关于如何进行负载测试的任何其他建议也将有很大帮助..
提前致谢!
守护线程是在所有其他线程完成时不阻止 JVM 退出的线程。
我相信如果您想等待主线程直到守护线程未完成,那么我建议不要使用守护线程,因为它不应该用于该用例。您可以使用 Thread#join
来等待您的主线程。
for(int i=0; i<10; i++) {
Thread t = new Thread("loadtest " + i);
t.setDaemon(true);
t.start();
t.join(); // main or parent thread will wait util the child thread finished
}
我相信在你的用例中你应该使用普通线程而不是守护进程。
我会冒险猜测你的 ExecutorService
没有工作,因为你在 Future
实例上调用 get()
它 returns 在你的循环。这个错误确实会导致你的处理被序列化,就好像你只有一个线程一样,因为另一个任务在第一个完成之前不会提交。
如果您确实需要使用 Callable
,请不要 get()
结果,直到您准备好在任务完成时无限期地阻塞——如果它们无法完成还没有提交。对于下载 URLs,最好使用 Runnable
,主线程提交 URLs 然后忘记任务;该任务可以独立完成其 URL.
如果您快速生成新任务,您可能会排队太多以至于 运行 内存不足。在这种情况下,您可以使用有界队列并直接使用 ThreadPoolExecutor
设置适当的拒绝处理程序。
负载测试不仅是关于 "hammering" 您的服务器的请求,行为良好的负载测试需要代表 真实用户 使用真实浏览器以及所有相关内容,例如:
所以我建议使用专门的 load testing tool which are capable of representing real user as close as possible and automatically taking care of aforementioned points. Also normally the load testing tools allow you to set rendezvous points 并提供大量指标和图表,以便您能够看到连接时间、网络延迟、吞吐量,将增加的负载与增加的响应相关联 time/number 错误等