在运行tomcat 6的web应用程序中,计划执行一个对象(而不是Servlet),以便从定义的文件夹中读取文件。读取文件后,文件内容将保存到数据库中。
为了获得更高的性能,需要多任务处理。我最初的方法是在读取文件后构建一个新线程,每个文件的任务在后台并行运行。例如,如果找到三个文件,就会创建三个线程。
然而,尽管tomcat配置已经将has线程设置为200多个,并且分配了32 to内存,但每次只有7-8个线程同时运行时。怎么了?或者多线程不是多任务处理的最佳实践?请帮帮忙。
此外(2014年3月14日)感谢您的建议。所以我的问题可以更具体一点: 1. ThreadPoolExecutor能提高性能吗? 2. NIO能提高性能吗?
这是原始代码:
String[] listFiles = folder.list();
for(int i=0; i<listFiles.length; i++) {
synchronized(globalHashMap) {
MyTask myTask = new MyTask(listFiles[i]);
globalHashMap.put(listFiles[i], myTask );
myTask.start();
}
}
MyTask {
String myFile;
Thread myThread;
public MyTask(String file) {
myFile = file;
}
public void start() {
myThread = new Thread(new Runnable() {
do {
readCnt = bufferedInputStream.read(bytesArray, 1024, 1);
...
} while(not end);
postProcessFunction();
synchronized(globalHashMap) {
globalHashMap.remove(myFile);
globalHashMap.notifyAll();
}
}
myThread.start();
}
}发布于 2014-03-13 17:19:48
Tomcat中的maxThreads设置并不意味着最大值。JVM可以拥有的线程的#。猫对此没有控制能力。它指定了最大值。Tomcat本身将创建工作线程#,以服务传入的HTTP请求。您的Java代码仍然可以创建它需要的任何线程。
至于为什么您只得到7-8线程,我必须查看代码才能确定。这个目录中有多少个文件?
我不知道你做了什么分析,但我经常听到“多线程”作为一种罐装的解决方案,使事情更快,这是一个非常危险的方式来解决问题。线程处理意味着解决非常具体的一组问题。这应该是最后的手段。尤其是在web应用程序中。Web容器使用多个类加载器动态部署、卸载和重新部署应用程序。线程创建了维护噩梦,并且经常阻止正确的类加载程序清理。
实际上,我曾见过多线程掩盖问题的场合。当我第一次加入我现在的公司时,我正在努力将SQL脚本部署到我们的数据库中,以应用bug修复程序。抱怨过程太慢,所以解决方案当然是通过多线程并行处理多个DB。我最近发现,脚本执行过程在每个脚本的末尾运行一个SQL语句(用于GRANT),而每个数据库只需2分钟。这句话很少有人需要。如果从一开始就正确地描述了这个过程,我的建议是删除不需要的代码,它将把这个过程从2-3个小时降到< 10分钟。现在,我们不得不维护一堆线程管理代码。
那么,现在我的问题是,,您描述了您的代码吗?正如@wallenborn所指出的,磁盘I/O可能是瓶颈。您的代码中也可以进行优化。
发布于 2014-03-13 17:12:12
Tomcat中的MaxThreads参数仅控制用于服务web请求的线程数量。web应用程序可以创建多少额外线程(除了可用内存)是没有限制的。代码一定有问题。
发布于 2014-03-13 17:18:02
在应用程序中创建比在应用服务器上运行的新线程不是一个好主意。这是个糟糕的做法。人们通常说永远不要这样做,因为您可以用完处理http请求的线程。
为了解决您的问题,最好的方法是使用jms。后台任务将向jms代理发送一条消息,以处理磁盘上的每个文件。Jms broker可以非常高效地处理多线程消息,并将为您控制所有多线程。
https://stackoverflow.com/questions/22385861
复制相似问题