需求背景
一个非主要功能特殊时期的高并发问题。该场景用到了parallelStream并发流提高查询速度,但是Java8的并发流线程池默认是ForkJoinPool,是全局共享的,任何用到了并发流的业务操作默认都是一个线程池。
问题:所有parallelStream业务操作都使用一个线程池就有可能互相影响。比如帮助中心查询用户权限+内容过滤都用到了parallelStream,相当于这些操作都在一个池子里。在并发的时候就有可能互相影响。
特点:非主要功能且在特殊时间(平时不咋用、平时不会集中使用)
解决方案
特殊账号用户、普通用户在不同的线程池中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| @Test void test() { List<Integer> list = new ArrayList<>(); for (int i = 0; i < 100; i++) { list.add(i); }
list.parallelStream().forEach((i) -> { System.out.println(Thread.currentThread().getName() + "........XXX"); try { Thread.sleep(500000L); } catch (InterruptedException e) { e.printStackTrace(); } });
}
@Test void testPrivate() { List<Integer> list = new ArrayList<>(); for (int i = 0; i < 100; i++) { list.add(i); } ForkJoinPool customThreadPool = new ForkJoinPool(4); customThreadPool.submit( () -> list.parallelStream().forEach((i) -> { System.out.println(Thread.currentThread().getName() + "........XXX"); try { Thread.sleep(50000L); } catch (InterruptedException e) { e.printStackTrace(); } })); try { Thread.sleep(500000L); } catch (InterruptedException e) { e.printStackTrace(); } }
|
控制台输出:
默认线程池输出:
自定义线程池输出:
可以看到默认线程池是commonPool,自定义线程池是2,做到了同一个parallelStream线程池的隔离。
注意:parallelStream默认线程池主线程也参与工作,会看到main也会打印,但是自定义线程池则没有
补充
Java中的parallelStream:Java中的parallelStream
自定义parallelStream:自定义parallelStream的threadpool -阿里云开发者社区 (aliyun.com)