[英]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.