java 某个方法执行时间需要10多分钟,出现超时错误,我该如何优化或设置超时时间?

海_狼 2014-06-09 08:33:20
我使用的是Struts2,EJB,某个方法执行时间需要10多分钟,内部需要远程调用EJB。有人说多线程可以解决,不知大家如何看,希望大牛给点建议,我该如何优化或设置超时时间?
等待ING……
...全文
963 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
海_狼 2014-06-13
  • 打赏
  • 举报
回复
引用 22 楼 ygycomon 的回复:
[quote=引用 21 楼 xiaoduishenghuogo 的回复:] [quote=引用 20 楼 ygycomon 的回复:] [quote=引用 17 楼 xiaoduishenghuogo 的回复:] [quote=引用 15 楼 ygycomon 的回复:] [quote=引用 13 楼 ygycomon 的回复:] 多线程不能解决这个问题,你的系统瓶颈在比对的方法,你拿着id一个一个去数据库里找,找一次10ms,你乘以10w算算要花多久?
就是一堆id比对嘛,一条sql就搞定了,一个一个比对明显是效率最低的处理方式[/quote] 还请大牛赐条sql语句?多谢多谢! 要完成的任务就是10w个ID和某个表中的id比对,查找数据库中没有但那10w个id里有的所有ID。[/quote] 把10w个id load进临时表里,做个join就出来了 或者SELECT * FROM table WHERE id IN (1,2,3,4) 查出结果再在内存取个差集也可以[/quote] 现在我已经解决这个问题了,我的思路是: 先从数据库中取出所有的id放在一个list里,然后跟我这边的list对比,当然,这里使用了特殊的算法,效率提高了不少,原来5分钟都执行不完,而现在只需要20几秒。算法如下: public static void main(String[] args) { int max_len = 50000; ArrayList<Integer> list1 = new ArrayList<Integer>(); ArrayList<Integer> list2 = new ArrayList<Integer>(); for (int i=0; i<max_len; i++) { list1.add((int)(Math.random()*max_len)); list2.add((max_len/2)+(int)(Math.random()*max_len)); } System.out.printf("list1:%d, list2:%d\n", list1.size(), list2.size()); long start = System.currentTimeMillis(); HashSet<Integer> set_all = new HashSet<Integer>(); for (int i=0; i<list1.size(); i++) { set_all.add(list1.get(i)); } HashSet<Integer> set_dup = new HashSet<Integer>(); ArrayList<Integer> list2_clean = new ArrayList<Integer>(); for (int i=0; i<list2.size(); i++) { if (set_all.add(list2.get(i))) { //in list2 but not in list1 list2_clean.add(list2.get(i)); } else { set_dup.add(list2.get(i)); //in list2 and also in list1 } } ArrayList<Integer> list1_clean = new ArrayList<Integer>(); for (int i=0; i<list1.size(); i++) { if (set_dup.add(list1.get(i))) { //in list1 but not in the duplicated set list1_clean.add(list1.get(i)); } } long end = System.currentTimeMillis(); System.out.printf("list1 clean:%d, list2 clean:%d\n", list1_clean.size(), list2_clean.size()); System.out.printf("time spent : %dms\n", end-start); }[/quote] 那你的问题就解决了。 再啰嗦一句:10w个id放进内存做处理是没什么压力,数据大了以后你内存就会爆。[/quote] 高手就是高手,以发展的眼光看问题,厉害,厉害!我会考虑这个问题的,谢谢啦!
致知Fighting 2014-06-12
  • 打赏
  • 举报
回复
引用 21 楼 xiaoduishenghuogo 的回复:
[quote=引用 20 楼 ygycomon 的回复:] [quote=引用 17 楼 xiaoduishenghuogo 的回复:] [quote=引用 15 楼 ygycomon 的回复:] [quote=引用 13 楼 ygycomon 的回复:] 多线程不能解决这个问题,你的系统瓶颈在比对的方法,你拿着id一个一个去数据库里找,找一次10ms,你乘以10w算算要花多久?
就是一堆id比对嘛,一条sql就搞定了,一个一个比对明显是效率最低的处理方式[/quote] 还请大牛赐条sql语句?多谢多谢! 要完成的任务就是10w个ID和某个表中的id比对,查找数据库中没有但那10w个id里有的所有ID。[/quote] 把10w个id load进临时表里,做个join就出来了 或者SELECT * FROM table WHERE id IN (1,2,3,4) 查出结果再在内存取个差集也可以[/quote] 现在我已经解决这个问题了,我的思路是: 先从数据库中取出所有的id放在一个list里,然后跟我这边的list对比,当然,这里使用了特殊的算法,效率提高了不少,原来5分钟都执行不完,而现在只需要20几秒。算法如下: public static void main(String[] args) { int max_len = 50000; ArrayList<Integer> list1 = new ArrayList<Integer>(); ArrayList<Integer> list2 = new ArrayList<Integer>(); for (int i=0; i<max_len; i++) { list1.add((int)(Math.random()*max_len)); list2.add((max_len/2)+(int)(Math.random()*max_len)); } System.out.printf("list1:%d, list2:%d\n", list1.size(), list2.size()); long start = System.currentTimeMillis(); HashSet<Integer> set_all = new HashSet<Integer>(); for (int i=0; i<list1.size(); i++) { set_all.add(list1.get(i)); } HashSet<Integer> set_dup = new HashSet<Integer>(); ArrayList<Integer> list2_clean = new ArrayList<Integer>(); for (int i=0; i<list2.size(); i++) { if (set_all.add(list2.get(i))) { //in list2 but not in list1 list2_clean.add(list2.get(i)); } else { set_dup.add(list2.get(i)); //in list2 and also in list1 } } ArrayList<Integer> list1_clean = new ArrayList<Integer>(); for (int i=0; i<list1.size(); i++) { if (set_dup.add(list1.get(i))) { //in list1 but not in the duplicated set list1_clean.add(list1.get(i)); } } long end = System.currentTimeMillis(); System.out.printf("list1 clean:%d, list2 clean:%d\n", list1_clean.size(), list2_clean.size()); System.out.printf("time spent : %dms\n", end-start); }[/quote] 那你的问题就解决了。 再啰嗦一句:10w个id放进内存做处理是没什么压力,数据大了以后你内存就会爆。
致知Fighting 2014-06-11
  • 打赏
  • 举报
回复
引用 17 楼 xiaoduishenghuogo 的回复:
[quote=引用 15 楼 ygycomon 的回复:] [quote=引用 13 楼 ygycomon 的回复:] 多线程不能解决这个问题,你的系统瓶颈在比对的方法,你拿着id一个一个去数据库里找,找一次10ms,你乘以10w算算要花多久?
就是一堆id比对嘛,一条sql就搞定了,一个一个比对明显是效率最低的处理方式[/quote] 还请大牛赐条sql语句?多谢多谢! 要完成的任务就是10w个ID和某个表中的id比对,查找数据库中没有但那10w个id里有的所有ID。[/quote] 把10w个id load进临时表里,做个join就出来了 或者SELECT * FROM table WHERE id IN (1,2,3,4) 查出结果再在内存取个差集也可以
海_狼 2014-06-11
  • 打赏
  • 举报
回复
引用 14 楼 redcenter 的回复:
如果你可以要求对方配合,最好的方式是当对方数据库表数据发生变化时通知你方,或者是定时推送一定时间内删除掉的IDs,你再对你的数据库进行处理。变化方应该是主动方,这样效率会改善很多。
这确实才是正确的做法。但是现在已经成了这样,他们那边根本就没有记录删除的ID,所以没办法这样处理。 如果以后完善系统的时候,可以考虑用这种方式实现。
海_狼 2014-06-11
  • 打赏
  • 举报
回复
引用 3 楼 ygycomon 的回复:
找到执行时间长的原因: 如果是自己系统内部的方法因为计算量太大或者其他什么原因,可以考虑把方法变成异步的,或者直接用其他更好的算法替代 如果是别人系统里的方法,远程调用时间太长,那你就没什么优化的手段了,只能把方法做成异步的。
我遇到这样的问题,由于方法执行时间过长,貌似超出了事务(或者是别的)设置的最大等待时间(亲测,貌似是5分钟),提示: Transaction rolled back,我知道这个时间肯定是可以设置的,但我不知道在哪设置,我用的是ejb的声明式事务,服务器容器用的是jboss。 还有,方法变成异步的以后,给用户的感受好了,那么异步的方法是不是也受这个最大等待时间限制呢?
海_狼 2014-06-11
  • 打赏
  • 举报
回复
引用 15 楼 ygycomon 的回复:
[quote=引用 13 楼 ygycomon 的回复:] 多线程不能解决这个问题,你的系统瓶颈在比对的方法,你拿着id一个一个去数据库里找,找一次10ms,你乘以10w算算要花多久?
就是一堆id比对嘛,一条sql就搞定了,一个一个比对明显是效率最低的处理方式[/quote] 还请大牛赐条sql语句?多谢多谢! 要完成的任务就是10w个ID和某个表中的id比对,查找数据库中没有但那10w个id里有的所有ID。
海_狼 2014-06-11
  • 打赏
  • 举报
回复
引用 20 楼 ygycomon 的回复:
[quote=引用 17 楼 xiaoduishenghuogo 的回复:] [quote=引用 15 楼 ygycomon 的回复:] [quote=引用 13 楼 ygycomon 的回复:] 多线程不能解决这个问题,你的系统瓶颈在比对的方法,你拿着id一个一个去数据库里找,找一次10ms,你乘以10w算算要花多久?
就是一堆id比对嘛,一条sql就搞定了,一个一个比对明显是效率最低的处理方式[/quote] 还请大牛赐条sql语句?多谢多谢! 要完成的任务就是10w个ID和某个表中的id比对,查找数据库中没有但那10w个id里有的所有ID。[/quote] 把10w个id load进临时表里,做个join就出来了 或者SELECT * FROM table WHERE id IN (1,2,3,4) 查出结果再在内存取个差集也可以[/quote] 现在我已经解决这个问题了,我的思路是: 先从数据库中取出所有的id放在一个list里,然后跟我这边的list对比,当然,这里使用了特殊的算法,效率提高了不少,原来5分钟都执行不完,而现在只需要20几秒。算法如下: public static void main(String[] args) { int max_len = 50000; ArrayList<Integer> list1 = new ArrayList<Integer>(); ArrayList<Integer> list2 = new ArrayList<Integer>(); for (int i=0; i<max_len; i++) { list1.add((int)(Math.random()*max_len)); list2.add((max_len/2)+(int)(Math.random()*max_len)); } System.out.printf("list1:%d, list2:%d\n", list1.size(), list2.size()); long start = System.currentTimeMillis(); HashSet<Integer> set_all = new HashSet<Integer>(); for (int i=0; i<list1.size(); i++) { set_all.add(list1.get(i)); } HashSet<Integer> set_dup = new HashSet<Integer>(); ArrayList<Integer> list2_clean = new ArrayList<Integer>(); for (int i=0; i<list2.size(); i++) { if (set_all.add(list2.get(i))) { //in list2 but not in list1 list2_clean.add(list2.get(i)); } else { set_dup.add(list2.get(i)); //in list2 and also in list1 } } ArrayList<Integer> list1_clean = new ArrayList<Integer>(); for (int i=0; i<list1.size(); i++) { if (set_dup.add(list1.get(i))) { //in list1 but not in the duplicated set list1_clean.add(list1.get(i)); } } long end = System.currentTimeMillis(); System.out.printf("list1 clean:%d, list2 clean:%d\n", list1_clean.size(), list2_clean.size()); System.out.printf("time spent : %dms\n", end-start); }
致知Fighting 2014-06-10
  • 打赏
  • 举报
回复
引用 9 楼 xiaoduishenghuogo 的回复:
[quote=引用 8 楼 ygycomon 的回复:] [quote=引用 6 楼 xiaoduishenghuogo 的回复:] [quote=引用 5 楼 ygycomon 的回复:] [quote=引用 4 楼 xiaoduishenghuogo 的回复:] [quote=引用 3 楼 ygycomon 的回复:] 找到执行时间长的原因: 如果是自己系统内部的方法因为计算量太大或者其他什么原因,可以考虑把方法变成异步的,或者直接用其他更好的算法替代 如果是别人系统里的方法,远程调用时间太长,那你就没什么优化的手段了,只能把方法做成异步的。
是这么回事,别人系统的某个表中有10多万条数据,然后我们系统的一个表中存有他们那个表里的所有ID,但是呢,人家表里的数据可能被删除了,现在我们需要根据我们表里记录的这10多万个ID跟他们表的id比对,并返回他们删除的那些ID。 你看我现在可不可以把我们表里的10万id分成10组,然后起10个线程,分别比对,这样是不是跟快点呢?[/quote] 你这个流程应该是把你这里的10w个id丢到他们那边去,然后返回被删掉的id 时间开销: 网络传输10w个id 比对id 网络传输被删除的id 你觉得哪个过程比较耗时? 我觉得应该是比对id这个过程,换句话说,系统的瓶颈出现在别人那里,你这边开多少个线程都没用[/quote] 没错,比对肯定是最耗时的,可是我觉得如果我这边起多个线程去比对,那不就相当于别人那边也有多个线程在同时比对嘛,怎么会没用呢?[/quote] 别人只有1个厨师,你给他一个菜单上写10个菜和给他10个菜单,有什么区别? 你可以试试就知道了[/quote] 那如果别人那边使用了多线程,是不是效率会提高呢?[/quote] 不要迷信多线程,性能优化要针对具体的业务场景来,你都不了解关联系统的实现细节,光说一个多线程能不能提高效率,这种问题是不可能有答案的
海_狼 2014-06-10
  • 打赏
  • 举报
回复
引用 8 楼 ygycomon 的回复:
[quote=引用 6 楼 xiaoduishenghuogo 的回复:] [quote=引用 5 楼 ygycomon 的回复:] [quote=引用 4 楼 xiaoduishenghuogo 的回复:] [quote=引用 3 楼 ygycomon 的回复:] 找到执行时间长的原因: 如果是自己系统内部的方法因为计算量太大或者其他什么原因,可以考虑把方法变成异步的,或者直接用其他更好的算法替代 如果是别人系统里的方法,远程调用时间太长,那你就没什么优化的手段了,只能把方法做成异步的。
是这么回事,别人系统的某个表中有10多万条数据,然后我们系统的一个表中存有他们那个表里的所有ID,但是呢,人家表里的数据可能被删除了,现在我们需要根据我们表里记录的这10多万个ID跟他们表的id比对,并返回他们删除的那些ID。 你看我现在可不可以把我们表里的10万id分成10组,然后起10个线程,分别比对,这样是不是跟快点呢?[/quote] 你这个流程应该是把你这里的10w个id丢到他们那边去,然后返回被删掉的id 时间开销: 网络传输10w个id 比对id 网络传输被删除的id 你觉得哪个过程比较耗时? 我觉得应该是比对id这个过程,换句话说,系统的瓶颈出现在别人那里,你这边开多少个线程都没用[/quote] 没错,比对肯定是最耗时的,可是我觉得如果我这边起多个线程去比对,那不就相当于别人那边也有多个线程在同时比对嘛,怎么会没用呢?[/quote] 别人只有1个厨师,你给他一个菜单上写10个菜和给他10个菜单,有什么区别? 你可以试试就知道了[/quote] 那如果别人那边使用了多线程,是不是效率会提高呢?
allkillers 2014-06-10
  • 打赏
  • 举报
回复
看来挺多人只是从书上或别人口中看到一堆多线程什么的,说什么提高速度,而没有真正从根本上理解什么是多线程,为什么要用多线程。 第一,在单cpu系统上,多线程只是给人错觉有两个任务同时在运行,一个时刻只有一个任务在运行,这一点大家应该都清楚。 第二,举个例子,你需要执行10000次计算,你开10个线程,每个线程计算1000次,和一个线程执行10000次,你觉得哪个快?线程切换所说开销不大,但也是有开销的,毫无疑问开10个线程还没有一个线程快。
致知Fighting 2014-06-10
  • 打赏
  • 举报
回复
引用 13 楼 ygycomon 的回复:
多线程不能解决这个问题,你的系统瓶颈在比对的方法,你拿着id一个一个去数据库里找,找一次10ms,你乘以10w算算要花多久?
就是一堆id比对嘛,一条sql就搞定了,一个一个比对明显是效率最低的处理方式
陆荃 2014-06-10
  • 打赏
  • 举报
回复
如果你可以要求对方配合,最好的方式是当对方数据库表数据发生变化时通知你方,或者是定时推送一定时间内删除掉的IDs,你再对你的数据库进行处理。变化方应该是主动方,这样效率会改善很多。
致知Fighting 2014-06-10
  • 打赏
  • 举报
回复
多线程不能解决这个问题,你的系统瓶颈在比对的方法,你拿着id一个一个去数据库里找,找一次10ms,你乘以10w算算要花多久?
海_狼 2014-06-10
  • 打赏
  • 举报
回复
引用 7 楼 u014467731 的回复:
[quote=引用 6 楼 xiaoduishenghuogo 的回复:] 没错,比对肯定是最耗时的,可是我觉得如果我这边起多个线程去比对,那不就相当于别人那边也有多个线程在同时比对嘛,怎么会没用呢?
这不是这样相当的吧。。 cup的读写能力在那里,都达到峰值了,不论你开多少线程,它的速度又不会变。。[/quote] 哦,我似乎明白了,如果你的方法执行时,CPU的占用率达到90%,那么,即使你再开几个线程,性能也不会提高多少了,对吧?
海_狼 2014-06-10
  • 打赏
  • 举报
回复
引用 10 楼 ygycomon 的回复:
[quote=引用 9 楼 xiaoduishenghuogo 的回复:] [quote=引用 8 楼 ygycomon 的回复:] [quote=引用 6 楼 xiaoduishenghuogo 的回复:] [quote=引用 5 楼 ygycomon 的回复:] [quote=引用 4 楼 xiaoduishenghuogo 的回复:] [quote=引用 3 楼 ygycomon 的回复:] 找到执行时间长的原因: 如果是自己系统内部的方法因为计算量太大或者其他什么原因,可以考虑把方法变成异步的,或者直接用其他更好的算法替代 如果是别人系统里的方法,远程调用时间太长,那你就没什么优化的手段了,只能把方法做成异步的。
是这么回事,别人系统的某个表中有10多万条数据,然后我们系统的一个表中存有他们那个表里的所有ID,但是呢,人家表里的数据可能被删除了,现在我们需要根据我们表里记录的这10多万个ID跟他们表的id比对,并返回他们删除的那些ID。 你看我现在可不可以把我们表里的10万id分成10组,然后起10个线程,分别比对,这样是不是跟快点呢?[/quote] 你这个流程应该是把你这里的10w个id丢到他们那边去,然后返回被删掉的id 时间开销: 网络传输10w个id 比对id 网络传输被删除的id 你觉得哪个过程比较耗时? 我觉得应该是比对id这个过程,换句话说,系统的瓶颈出现在别人那里,你这边开多少个线程都没用[/quote] 没错,比对肯定是最耗时的,可是我觉得如果我这边起多个线程去比对,那不就相当于别人那边也有多个线程在同时比对嘛,怎么会没用呢?[/quote] 别人只有1个厨师,你给他一个菜单上写10个菜和给他10个菜单,有什么区别? 你可以试试就知道了[/quote] 那如果别人那边使用了多线程,是不是效率会提高呢?[/quote] 不要迷信多线程,性能优化要针对具体的业务场景来,你都不了解关联系统的实现细节,光说一个多线程能不能提高效率,这种问题是不可能有答案的[/quote] 我了解他们系统的实现,他们就是循环我传过去的id List,然后一个一个的去数据库找。而且我也可以改他们的代码,现在的问题是,我想知道多线程能否解决这个问题?
致知Fighting 2014-06-09
  • 打赏
  • 举报
回复
引用 4 楼 xiaoduishenghuogo 的回复:
[quote=引用 3 楼 ygycomon 的回复:] 找到执行时间长的原因: 如果是自己系统内部的方法因为计算量太大或者其他什么原因,可以考虑把方法变成异步的,或者直接用其他更好的算法替代 如果是别人系统里的方法,远程调用时间太长,那你就没什么优化的手段了,只能把方法做成异步的。
是这么回事,别人系统的某个表中有10多万条数据,然后我们系统的一个表中存有他们那个表里的所有ID,但是呢,人家表里的数据可能被删除了,现在我们需要根据我们表里记录的这10多万个ID跟他们表的id比对,并返回他们删除的那些ID。 你看我现在可不可以把我们表里的10万id分成10组,然后起10个线程,分别比对,这样是不是跟快点呢?[/quote] 你这个流程应该是把你这里的10w个id丢到他们那边去,然后返回被删掉的id 时间开销: 网络传输10w个id 比对id 网络传输被删除的id 你觉得哪个过程比较耗时? 我觉得应该是比对id这个过程,换句话说,系统的瓶颈出现在别人那里,你这边开多少个线程都没用
海_狼 2014-06-09
  • 打赏
  • 举报
回复
引用 3 楼 ygycomon 的回复:
找到执行时间长的原因: 如果是自己系统内部的方法因为计算量太大或者其他什么原因,可以考虑把方法变成异步的,或者直接用其他更好的算法替代 如果是别人系统里的方法,远程调用时间太长,那你就没什么优化的手段了,只能把方法做成异步的。
是这么回事,别人系统的某个表中有10多万条数据,然后我们系统的一个表中存有他们那个表里的所有ID,但是呢,人家表里的数据可能被删除了,现在我们需要根据我们表里记录的这10多万个ID跟他们表的id比对,并返回他们删除的那些ID。 你看我现在可不可以把我们表里的10万id分成10组,然后起10个线程,分别比对,这样是不是跟快点呢?
致知Fighting 2014-06-09
  • 打赏
  • 举报
回复
找到执行时间长的原因: 如果是自己系统内部的方法因为计算量太大或者其他什么原因,可以考虑把方法变成异步的,或者直接用其他更好的算法替代 如果是别人系统里的方法,远程调用时间太长,那你就没什么优化的手段了,只能把方法做成异步的。
致知Fighting 2014-06-09
  • 打赏
  • 举报
回复
引用 6 楼 xiaoduishenghuogo 的回复:
[quote=引用 5 楼 ygycomon 的回复:] [quote=引用 4 楼 xiaoduishenghuogo 的回复:] [quote=引用 3 楼 ygycomon 的回复:] 找到执行时间长的原因: 如果是自己系统内部的方法因为计算量太大或者其他什么原因,可以考虑把方法变成异步的,或者直接用其他更好的算法替代 如果是别人系统里的方法,远程调用时间太长,那你就没什么优化的手段了,只能把方法做成异步的。
是这么回事,别人系统的某个表中有10多万条数据,然后我们系统的一个表中存有他们那个表里的所有ID,但是呢,人家表里的数据可能被删除了,现在我们需要根据我们表里记录的这10多万个ID跟他们表的id比对,并返回他们删除的那些ID。 你看我现在可不可以把我们表里的10万id分成10组,然后起10个线程,分别比对,这样是不是跟快点呢?[/quote] 你这个流程应该是把你这里的10w个id丢到他们那边去,然后返回被删掉的id 时间开销: 网络传输10w个id 比对id 网络传输被删除的id 你觉得哪个过程比较耗时? 我觉得应该是比对id这个过程,换句话说,系统的瓶颈出现在别人那里,你这边开多少个线程都没用[/quote] 没错,比对肯定是最耗时的,可是我觉得如果我这边起多个线程去比对,那不就相当于别人那边也有多个线程在同时比对嘛,怎么会没用呢?[/quote] 别人只有1个厨师,你给他一个菜单上写10个菜和给他10个菜单,有什么区别? 你可以试试就知道了
小螃蟹111 2014-06-09
  • 打赏
  • 举报
回复
引用 6 楼 xiaoduishenghuogo 的回复:
没错,比对肯定是最耗时的,可是我觉得如果我这边起多个线程去比对,那不就相当于别人那边也有多个线程在同时比对嘛,怎么会没用呢?
这不是这样相当的吧。。 cup的读写能力在那里,都达到峰值了,不论你开多少线程,它的速度又不会变。。
加载更多回复(1)

67,516

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧