I have a simple object
@Data
@Builder
public class Address {
private Long id;
private String street;
}
I make delombok of @Builder
annotation and I see next code generated
@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 + ")";
}
}
}
Looking to this I see that builder is some static inner class of my Address class.
Let's imagine that I have 2 threads that uses builder
executing in parallel.
First thread creates this local variable
Address address = Address.builder()
.id(1L)
.street("street 1")
.build();
Second one creates this local one
Address address = Address.builder()
.id(2L)
.street("street 2")
.build();
Looking to the implementation of lombok that uses static classes is it possible that running in parallel I'll have sometimes inside one of the threads an object id=1L street="street 2"
or id=2L street="street 1"
?
It is thread safe. In the method builder a new AddressBuilder object is created, so it is always working with a new object. The methods are only using local variables, no shared variables.
To test this, I wrote the wollowing unit test:
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();
}
}
with vmlens, a tool to detect race conditions, and it did not found as expected any races.
The ConcurrentTestRunner used in the unit test is running the test method with 4 threads in parallel.