I don't think the Builders should be singleton.
If you really really wanted to I guess you could do something like this:
public final class Builder{
private static final Builder instance = new Builder();
private Part part1= null;
private Part part2= null;
...
public static Builder getInstance() {
return instance;
}
private Builder() { /*singleton */ }
public Builder buildPart1(Part p){
part1 = p;
return this;
}
...build other parts similar;
Product getResult(){
return new ConcreteProduct(part1, part2 ...);
}
}
But by re-using the same singleton instance, you would have to make sure you set all the values correctly and not accidentally re-use old values from previously built products.
Even with proper synchronization, I think the potential for bugs and surprises from other threads/ previous built production values leaking into your Product would not make it worth it.