一加科技|面试必须要掌握的内容:多线程与Spring容器事务机制( 二 )


   

   <b>private</b> List<List<Integer>> getBatches(List collection <b>int</b> batchSize) {
       <b>return</b> IntStream.iterate(0 i -> i < collection.size() i -> i + batchSize)
               .mapToObj(i -> collection.subList(i Math.min(i + batchSize collection.size())))
               .collect(Collectors.toList());
   

   <b>private</b> List<Integer> flatList(List> listOfLists) {
       <b>return</b> listOfLists.stream().collect(ArrayList::<b>new</b> List::addAll List::addAll);
   
</font>

实际的调用被委托给一个处理服务的实现 , 但Decorator负责跨线程的工作分配和收集结果 。
装饰器模式的实现使客户端代码不知道实际的实现 。 可以直接注入单线程版本 , 也可以注入多线程版本 , 而无需直接改变客户端代码 。
为了理解客户端代码可能是什么样子的 , 让我们看一下一个简单的单元测试 。
@RunWith( SpringJUnit4ClassRunner.<b>class</b> )
@SpringBootTest(properties = { <font>\"service.parallel=false\"</font><font> )<b>public</b> <b>class</b> ProcessingServiceTest {
   
   @Autowired
   ProcessingService processingService;
   
   ProcessingService processingServiceDecorator;
   
   @Test    <b>public</b> <b>void</b> shouldRunParallelProcessingUsingDecorator() {
       processingServiceDecorator = <b>new</b> ProcessingServiceParallelRunDecorator(processingService);
       List objectIds = Arrays.asList(<b>new</b> Integer[
{ 1 2 3 4 5 6 7 8 9 10 11 12);
       
       List resultList = processingServiceDecorator.processObjects(objectIds);
       
       Assert.assertEquals(objectIds resultList);
   
   
</font>

该代码传递了一个objectIds的列表 , 并运行测试中明确创建的Decorator服务 。
预计由于内部配置的chunk大小为10 , 两个线程将处理数据 。 通过检查日志 , 我们可以看到以下几行 。
ProcessingDBService: Running in thread ForkJoinPool.commonPool-worker-3 with object ids [1 2 3 4 5 6 7 8 9 10
ProcessingDBService: Running in thread main with object ids [11 12


在正好两个线程中 , 并行流使用主线程进行处理 , 第二个线程在它们之间分配工作 。
这种处理的一个重要方面是事务处理 。 前10个元素在一个事务中被处理 , 而最后2个元素在另一个事务中被处理 。
如果你看一下ProcessingDBService , 你会看到公共方法被注解了@Transactional注解 。 这就是Spring预计的工作方式:它负责在专用的ThreadLocal对象中为每个线程保存事务上下文 , 不支持在一个事务中运行多个线程 。
【一加科技|面试必须要掌握的内容:多线程与Spring容器事务机制】本文没有涉及错误处理 , 但会在以后的文章中加以阐述 。 还有一点需要注意的是 , Decorator类中的依赖注入是基于构造器注入的 。 为了被Spring容器所管理 , 你可能需要在构造器中使用@Qualifier 。