Olá!
Estou com uma dúvida com relação a classe StringBuffer em um exercício do Test Killer:
O Exame TestKiller afirma que este código é Thread-Safe (Questão 89):
- public String toString() {
- StringBuffer buffer = new StringBuffer();
- buffer.append(?<?);
- buffer.append(this.name);
- buffer.append(?>?);
- return buffer.toString();
- }
Pelo que entendi até agora, se duas threads acessassem esse método ao mesmo o resultado poderia ser diferente do esperado e seria necessário que o método toString() fosse declarado como synchronized para que o código se tornasse Thread-safe.
E isso me deixou com essa dúvida. O código é mesmo Thread-safe?
Grato.
Paulo Gervasio
Cara eu sei que StringBuffer é Thread Safe agora não sei se por usar um objeto StringBuffer esse método viraria Thread Safe…
Não é thread-safe.
É um erro comum de quem está programando com threads imaginar que, pela classe StringBuffer ser considerada thread-safe, todas as operações com ela também serão.
O que queremos dizer com o StringBuffer ser thread-safe é que não há como duas threads chamarem o método append ao mesmo tempo, e isso corromper uma inserção no append. Agora, não há garantias de thread-safety entre duas chamadas do método append. Essa garantia você só tem quando sincroniza a classe que usa o StringBuffer.
Aliás, esse é um dos grandes motivos pelo qual ter um StringBuffer geralmente é inútil e devemos preferir o StringBuilder. Geralmente, a classe que usa o buffer terá que ser sincronizada, e isso já garante um acesso seguro ao builder.
[quote=ViniGodoy]Não é thread-safe.
É um erro comum de quem está programando com threads imaginar que, pela classe StringBuffer ser considerada thread-safe, todas as operações com ela também serão.
O que queremos dizer com o StringBuffer ser thread-safe é que não há como duas threads chamarem o método append ao mesmo tempo, e isso corromper uma inserção no append. Agora, não há garantias de thread-safety entre duas chamadas do método append. Essa garantia você só tem quando sincroniza a classe que usa o StringBuffer.
Aliás, esse é um dos grandes motivos pelo qual ter um StringBuffer geralmente é inútil e devemos preferir o StringBuilder. Geralmente, a classe que usa o buffer terá que ser sincronizada, e isso já garante um acesso seguro ao builder.[/quote]
ta explicado!! 
Legal, entendido!
Hashtable e Vector têm métodos “synchronized” e também não são muito utilizadas.
Existem outras classes padrão java que possuem métodos synchronzed?
Grato.
Paulo Gervasio.
Que eu me lembre, eram essas 3: HashTable, Vector e StringBuffer.
Todas elas foram substituídas por versões não sincronizadas: HashMap, ArrayList e StringBuilder.
Existem classes no pacote java.util.synchronized que tem sincronização, mas que justamente servem como tipos thread-safe. Como é o caso da classe AtomicInt, ou da ReentrantLock, por exemplo.
Um detalhe. Sincronização é uma das formas de se obter thread-safety, mas não a única. Classes imutáveis como String, por exemplo, são naturalmente thread-safe, mesmo sem os métodos synchronized. O uso de thread-locals para a duplicação dos dados compartilhados também pode garantir thread-safety.
Ou seja, esse assunto é um pouco mais complexo e interessante do que as certificações geralmente levam a crer.