I have an immutable class "Immutable" with a nested builder "Immutable.Builder" to avoid concurrency issues.
Now i have an instance "randomInstance" of a random class "RandomClass" with a field "Immutable immutable = Immutable.Builder.instanceOf()".
Now i have two concurrent threads who instantiate Immutable.Builder instances off of the Immutable instance in that field, make changes to the builder, call build() to get a new Immutable instance, and overwrite the instance of that field with the new Immutable instance. The classic use case for the builder pattern, no?
When both threads instantiate the builder off of the same instance of field before one of them writes the new instance back into the field, the "changes" made by the first thread that writes its new instance in the field will be subject to the garbage collector and essentially lost, as soon as the second thread writes its new instance into the field, is it not?
What approaches are there, to make sure, all "changes" are taken into account?
EDIT I didn't this this question would benefit from a working example but apparently I was wrong, so here it is as slim as i could do it:
public class Main {
public static void main(String[] args) {
Immutable immutable = new Immutable.Builder(0).build();
RandomClass randomClass = new RandomClass();
java.lang.Thread t1 = new java.lang.Thread(new Thread(randomClass, true));
t1.start();
java.lang.Thread.sleep(500);
java.lang.Thread t2 = new java.lang.Thread(new Thread(randomClass, false));
t2.start();
}
}
public class RandomClass {
public Immutable immutable = new Immutable.Builder(0).build();
}
public class Immutable {
private int field;
private Immutable(Builder builder) {
this.field = builder.field;
}
public static class Builder {
private int field;
public Builder(int arg) {
this.field = arg;
}
public Builder setField(int arg) {
this.field = arg;
return this;
}
public Immutable build() {
return new Immutable(this);
}
}
public Builder builder() {
return new Builder(this.field);
}
}
import java.util.Random;
public class Thread implements Runnable {
private RandomClass randomClass;
public Thread(RandomClass randomClass) {
this.randomClass = randomClass;
}
@Override
public void run() {
while(true) {
int i = new Random().nextInt();
this.randomClass.immutable = this.randomClass.immutable.builder().setField(i).build();
}
}
}