前几天上线一个项目,因为涉及到需要往redis数据库写入数据,所以写了一个多线程的类,创建多个线程王数据库写入数据,结果创建的57个线程中,只有24个线程完成了数据的处理,剩下的33个线程没有执行,问题到现在还没查询出来,现在把线程中的一些点列出来,以后有机会仔细研究一下。
ExecutorService service = Executors.newCachedThreadPool();
List<Future<RiskerCounter>> countList = new ArrayList<>();
多线程的线程池是用Executors创建的。新建了一个ArrayList,用来存放需要写入的数据。
for (int i = 0; i < thread; i++) {
List<WhiteListActiveFrom> list = whiteLists.subList(i * preFetch,
(i + 1) * preFetch > whiteLists.size() ? whiteLists.size() : (i + 1) * preFetch);
Future<RiskerCounter> future = service.submit(new ThreadRunner(list));
countList.add(future);
}
通过集合subList的方法,获取当前线程需要处理的数据,获得一个list,放入线程中处理。
线程中就是基本的数据set和存储了,没什么需要注意的点。
有几个问题需要注意一下。一个是:本地启动,发送请求,线程全部启动,也全部处理成功了,所以,代码理论上是没有问题的。当时在线上服务器跑的时候,只有不到一半的线程。另外一点是,需要的线程数目,根据日志来看,是没有问题的,创建了需要的线程数,因为需要的最大的线程数的那个线程完成了数据处理,剩下的一部分线程,在处理问题的时候,日志上打印出了处理数据的是第几个线程,另外那些线程全部丢失,没有进到数据处理的线程当中。当时猜测是不是别的占用了这些线程,但有另外的一个疑惑是,为什么每次处理成功的是固定的24个线程,如果线程被占用,为什么都是占用33个。
暂时没发现问题的所在,先写此文,以待有机会探究。