lundi 23 mai 2016

Thread-safe implementation of builder pattern

There is an article that I came across while I was looking for a good practice of builder pattern.

In the article, the author mentions about something that drew my attention. the pattern being thread safe.

The first variation of build() method is thread-safe:

public User build() {
    User user = new user(this);
    if (user.getAge() > 120) {
        throw new IllegalStateException("Age out of range"); // thread-safe
    }
    return user;
}

Whereas, this one is not:

public User build() {
    if (age > 120) {
        throw new IllegalStateException("Age out of range"); // bad, not thread-safe
    }
    // This is the window of opportunity for a second thread to modify the value of age
    return new User(this);
}

Although, I think a better approach would be throwing IllegalStateException in the setters:

public User build() {
    User u = null;
    try {
        u = new User(this);
    }
    catch(IllegalStateException e){
        e.printStackTrace();
    }
    return u;
}

where the constructor looks like this:

private User(UserBuilder builder)
{
    setAge(builder.age);
}

and the setter is:

void setAge(int age) throws IllegalStateException {
    if(age > 0 && age < 120) this.age = age;
    else throw new IllegalStateException("Age out of range");
}

would my approach still be thread-safe? If not, why? And what is the best way to implement the builder pattern in a thread-safe way?

Aucun commentaire:

Enregistrer un commentaire