我在一个函数中有一个 for 循环,我打算并行化它,但不确定多个线程的负载是否会超过并发的好处。
我需要的只是将不同的日志文件发送到相应的接收者。暂时假设接收器的数量不会超过 10 个。如果我并行发送日志文件,而不是连续发送日志文件,是否会更有效?
for(int i=0; i < receiversList.size(); i++)
{
String receiverURL = serverURL + receiversList.get(i);
HttpPost method = new HttpPost(receiverURL);
String logPath = logFilesPath + logFilesList.get(i);
messagesList = readMsg(logPath);
for (String message : messagesList) {
StringEntity entity = new StringEntity(message);
log.info("Sending message:");
log.info(message + "\n");
method.setEntity(entity);
if (receiverURL.startsWith("https")) {
processAuthentication(method, username, password);
}
httpClient.execute(method).getEntity().getContent().close();
}
Thread.sleep(500); // Waiting time for the message to be sent
}
另外请告诉我如果它能工作的话我怎样才能使它并行?我应该手动执行还是使用 ExecutorService?
最佳答案
All I need is to send different log files to corresponding receivers. For the time being lets say number of receivers won't be more than 10. Instead of sending log files back to back, is it more efficient if I send them all parallel?
在我们确定并行执行此操作是否会给您带来任何好处之前,需要询问很多问题。您提到了“接收器”,但您真的是在谈论不同网址上的不同接收服务器,还是所有线程都将其日志文件发送到同一服务器?如果是后者,那么并发速度的提高可能会很小。单个线程应该能够很好地填充网络管道。
此外,如果消息很小,您可能不会获得任何速度提升。只有大消息才会花费任何时间,并且如果并行发送,则会真正节省成本。
我最熟悉的是ExecutorService
类。你可以这样做:
ExecutorService threadPool = Executors.newFixedThreadPool(10);
...
threadPool.submit(new Runnable() {
// you could create your own Runnable class if each one needs its own httpClient
public void run() {
StringEntity entity = new StringEntity(message);
...
// we assume that the client is some sort of pooling client
httpClient.execute(method).getEntity().getContent().close();
}
}
});
如果您希望将这些消息排队并在后台线程中发送它们,以免减慢程序速度,那么会更好。然后您可以将消息提交到threadPool
并继续前进。或者您可以将它们放入 BlockingQueue<String>
并有一个线程取自 BlockingQueue
并调用 httpClient.execute(...)
.
更多实现细节来自此 good ExecutorService
tutorial .
最后,如何将所有消息放入一个实体中并在服务器上划分消息。尽管您可能无法控制服务器处理程序代码,但这将是最有效的。
关于java - 将 for 循环转换为多线程 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38581697/