一次聚类引发的一系列问题(多线程篇-多线程慢于单线程)

为了提升聚类效率,使用多线程是必须的,在此过程中对多线程又多了一些了解

一、多线程中尽量不可大量使用Math.random()。由于Math.random()中会使用CAS机制,所以频繁使用会导致线程执行速度变慢。可自行书写单线程代码和多线程代码测试,产生同样多个随机数,会发现多线程执行速度是慢于单线程的。

二、多线程中不要大量创建对象,因为大量创建对象会导致垃圾回收,在垃圾回收的过程中多次产生了STW,本人书写的多线程代码中就是由于调用了CollectionsUtils.retainAll(List, List)方法,该方法会产生新的Collection对象,线程执行过程中该方法的调用次数太多,导致了创建的对象过多,以致多线程执行效率慢于单线程。最后使用了一个ThreadLocal保存一个List,重新写了retainAll方法,每次从ThreadLocal中获取List,先clear再使用,多线程执行速度大大提升。

三、聚类数据量大,但是每一次执行的时间较短,只有几十毫秒,而每次执行都使用线程池的commit方法,那么线程执行结束到下次执行中间线程初始化和资源回收等时间就浪费的比较多了,因此,应当把数据分配给线程,或者每个线程去取需要执行的数据,执行完一次之后继续执行,而不是频繁调用commit方法。我的解决方案是使用AtomicInteger来保证不取到相同的数据(数据集是数组)。

 

posted @ 2019-08-28 15:49  五十一步  阅读(334)  评论(0编辑  收藏  举报