如何使Java应用程序更快?

时间:2013-05-04 18:10:04

标签: java multithreading

我有一个计费守护程序,必须以非常快的方式处理数十万个数据。我实现了ExecutorSerivce进行并行处理。它确实提高了速度,但不是很多。处理1,00,000条记录大约需要2.5到3个小时。如何在半小时内处理这些数据更快?

我已经为执行设置写了以下内容:

-Xms2048M -Xmx2048M -XX:MaxPermSize=256m

我尝试使用1个生产者和4个使用者实现Producer Consumer模型。每个列表可以包含10,000条记录。

ArrayBlockingQueue<BillableList> list =new ArrayBlockingQueue<BillableList>(10);

ExecutorService threadPool = Executors.newFixedThreadPool(5);
threadPool.execute(new Consumer("pool1", list)); 
threadPool.execute(new Consumer("pool2", list));
threadPool.execute(new Consumer("pool3", list));
threadPool.execute(new Consumer("pool4", list));
Future producerStatus = threadPool.submit(new Producer("Producer", list)); 
producerStatus.get(); 
threadPool.shutdown(); 

在将记录更新到数据库时,我也收到了很多“超出数据库锁等待超时”的异常。这是因为不同的消费者同时尝试同一个用户吗?如何让不同的消费者从ArrayBlockingQueue的列表中获取不同的数据?

2 个答案:

答案 0 :(得分:10)

唯一可能的答案是“使用分析器并找出它为什么慢”。当您不知道问题出在何处时,您无法对问题采取任何措施。你打算怎么做,选择一个随机函数并进行微优化?分析器数据或永远不会发生任何事情。

答案 1 :(得分:1)

  

如何在半小时内处理这些数据更快?

如果添加线程没有帮助,那么你很可能不受我的CPU限制,而是受到其他因素的限制。最有可能是磁盘或网络IO。如上所述,分析代码应该向您显示罪魁祸首。

  

在将记录更新到数据库时,我也收到了很多“超出数据库锁等待超时”的异常。

这是你的大线索。无论有多少线程正在处理作业,如果它们都在等待数据库,那么添加线程并不会使它更快。

以下是一些想法:

  • 提高数据库框的物理速度。 SSD可以为IO密集型操作提供奇妙的改进。由于磁盘缓存,增加内存也可以带来巨大的胜利。
  • 考虑分片数据并写入多个数据库实例。根据您的架构,这可能无法实现。
  • 考虑关闭自动提交并在每次约100次操作后手动提交。
  • 注意索引。如果您正在进行某种批量加载,通常如果关闭索引,您的插入将运行得更快。最后添加索引需要一段时间,但仍然是一个胜利。
  • 此外,如果您正在进行查询,请确保您在需要时拥有良好的索引。检查数据库日志以查看哪些查询花了太长时间才能查看是否缺少关键位置的某些索引。