繁体   English   中英

Lombok @Singular - 如何使其线程安全?

[英]Lombok @Singular - how to make it threadsafe?

这是一个关于Lombok 的@Builder@Singular注解和线程安全的问题

作为一个简化的例子,考虑这个类:

@Builder
public class Avengers {
    @Singular
    private List<String> members;
}

这会生成一个构建器,我可以在其中执行此操作:

final Avengers team = Avengers.builder()
    .member("Iron Man")
    .member("Thor")
    .member("Captain America")
    .build();
System.out.println(team.getMembers());  // ["Iron Man", "Thor", "Captain America"]

现在解决问题- 我想要做的是这样的事情(再次,这被过度简化了):

final AvengersBuilder teamBuilder = Avengers.builder();
executorService.submit(() -> teamBuilder.member("Iron Man"));
executorService.submit(() -> teamBuilder.member("Thor"));
executorService.submit(() -> teamBuilder.member("Captain America"));
// shutdown and awaitTermination would go here

final Avengers team = teamBuilder.build();

为什么这是个问题?

生成的构建器不是线程安全的(Lombok 通过ArrayList支持它),因此team.getMembers()的结果可能不完整或因此处于不一致状态。

问题:有没有办法让 Lombok 生成一个线程安全构建器,让我使用这种“单一”模式?

到目前为止,我的解决方法是避免使用 Singular 并创建自己的线程安全构建器方法,但我希望消除这个样板文件。

这是不可能的。 无论如何,尝试跨多个线程共享一个构建器是非常不寻常的。 您最好存储所有结果,然后迭代它们并将它们全部添加到同一线程上的构建器中。

List<Future<String>> futures = new ArrayList<>();  
futures.add(executorService.submit(() -> "Iron Man"));
futures.add(executorService.submit(() -> "Thor"));
futures.add(executorService.submit(() -> "Captain America"));
// shutdown and awaitTermination would go here

final AvengersBuilder teamBuilder = Avengers.builder();
for (Future<String> future : futures) {
    try {
        teamBuilder.member(future.get());
    }
    catch (InterruptedException | ExecutionException e) {
        // do something
    }
}
final Avengers team = teamBuilder.build();

这仍然使项目的生成并行化,这可能是缓慢的部分。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM