Multithreading 是龙目山';s builder线程安全?

Multithreading 是龙目山';s builder线程安全?,multithreading,thread-safety,builder,lombok,Multithreading,Thread Safety,Builder,Lombok,我有一个简单的对象 @Data @Builder public class Address { private Long id; private String street; } 我对@Builder进行了delombok注释,并看到生成的下一个代码 @Data public class Address { private Long id; private String street; @java.beans.ConstructorProperties

我有一个简单的对象

@Data
@Builder
public class Address {
    private Long id;
    private String street;
}
我对
@Builder
进行了delombok注释,并看到生成的下一个代码

@Data
public class Address {
    private Long id;
    private String street;

    @java.beans.ConstructorProperties({"id", "street"})
    Address(Long id, String street) {
        this.id = id;
        this.street = street;
    }

    public static AddressBuilder builder() {
       return new AddressBuilder();
    }

    public static class AddressBuilder {
        private Long id;
        private String street;

        AddressBuilder() {
        }

        public AddressBuilder id(Long id) {
            this.id = id;
            return this;
        }

        public AddressBuilder street(String street) {
            this.street = street;
            return this;
        }

        public Address build() {
            return new Address(id, street);
        }

        public String toString() {
            return "Address.AddressBuilder(id=" + this.id + ", street=" + this.street + ")";
        }
    }
}
看看这个,我发现builder是Address类的某个静态内部类

假设我有两个线程使用
builder
并行执行

第一个线程创建这个局部变量

Address address = Address.builder()
    .id(1L)
    .street("street 1")
    .build();
第二个创建了这个本地的

Address address = Address.builder()
    .id(2L)
    .street("street 2")
    .build();

看看使用静态类的lombok的实现,有没有可能并行运行,有时在其中一个线程中会有一个对象
id=1L street=“street 2”
id=2L street=“street 1”

它是线程安全的。在方法生成器中,将创建一个新的AddressBuilder对象,因此它始终使用一个新对象。这些方法只使用局部变量,没有共享变量

为了测试这一点,我编写了wollowing单元测试:

import com.anarsoft.vmlens.concurrent.junit.ConcurrentTestRunner;
@RunWith(ConcurrentTestRunner.class)
public class TestLombok {
@Test
public void testOne()
{
    Address address = Address.builder()
            .id(1L)
            .street("street 1")
            .build();

}
@Test
public void testTwo()
{
    Address address = Address.builder()
            .id(2L)
            .street("street 2")
            .build();
}   
}
使用,一个检测比赛条件的工具,它没有像预期的那样找到任何比赛

单元测试中使用的ConcurrentTestRunner使用4个线程并行运行测试方法