Double-checked locking

Tempos atrás estive desenvolvendo um sistema com múltiplas threads e que necessitavam acessar um único banco de dados.

Imagine um cenário onde duas threads distintas vão criar um novo registro. Esse registro possui o mesmo identificador único. Não pode haver valores duplicados nessa tabela.

Como garantir que duas threads cadastrem o mesmo registro ao mesmo tempo, sem duplicar o registro?

Uma saída que encontramos na empresa foi realizar o double checked locking. Essa técnica utiliza o synchronized.

class CarBO {

    public Car createAndSaveCar(String name) {

        Car result = this.getCarByName(name);

        if (result == null) {
            synchronized(this) {
                result = this.getCarByName(name);
                if (result == null) {
                    result = new Car();
                    result.setName(name);
                    this.save(result);
                }
            }
        }
        return result;
    }

    // other methods
}

A primeira chamada do método getCarByName() não precisa ser sincronizado, o que significa que duas threads podem fazer essa chamada.

Caso não exista nenhum resultado para o nome desse carro no banco de dados o método é sincronizado e uma nova consulta é realizada. A primeira thread que acessar esse bloco sincronizado criará um novo registro do carro no banco de dados libera o acesso para a segunda thread. A segunda thread acessa o bloco e realiza a nova consulta. O retorno será a existência do carro no banco de dados e não será necessário criar o carro, garantindo que não haja registros duplicados.

Bom… espero que ajude vocês nos desafios do dia-a-dia.

One response to “Double-checked locking

Leave a Reply

Your email address will not be published. Required fields are marked *