线程优化
昨天看到一同事的导出代码,单线程,看着就觉得还是差了点东西。然后就想进行一番改造,然后就找来了future和callable。
Callable接口类似于Runnable,从名字就可以看出来了,但是Runnable不会返回结果,并且无法抛出返回结果的异常,而Callable功能更强大一些,被线程执行后,可以返回值,这个返回值可以被Future拿到,也就是说,Future可以拿到异步执行任务的返回值。
简单来说就是一个是执行任务,然后它带着任务执行的结果回来。
简单看下下面的demo
1 | import java.util.ArrayList; |
参考了这个例子,我就改造了导出的那段代码,1w2数据从原来的6-8s 到现在的2-3s,虽然不是很多,但是也是一大进步,后来想了下,时间其实就花在了查询的sql,如果sql 再继续优化下去的的话应该可以突破到1s执行返回的。但因为还有新需求要进行,我就不再细究下去了。
改造的时候,同样我也是根据查询的数据量来新建任务执行,使用了for循环,本来公司已经提供了线程池fixedPool(100)的,我就不用自己再创建了。
出现的问题
- future 没有表示返回来的这堆数据是谁的
于是我就对返回变量进行了修改,返回一个map,标识这个数据是我的,后面根据map的key获取数据。 - size 数据量的大小影响任务的执行
查询数据使用了limit 字段每次查询1000 2000 3000 500 这几个size 都试过,似乎值越大越好,一次查询数据量比多次查询数据量效率要高。因为3000恐怕生产环境的数据会比较多,后来我就改成了2000。 - mysql 索引 不合理
索引建不好,导致查询sql也是很慢的,查询的那个表使用了多列索引,问题就出在这了,使用sql的执行计划看了下,查询的字段虽然有索引但是没有使用到,因为多列索引的第一个不是我的查询字段,导致查询效率会有小小的降低,我也没跟负责人说,毕竟也不是很大的问题,差的时间不是很多。